본문 바로가기

알고리즘/백준

[백준 알고리즘 자바]1157 : 단어 공부

https://www.acmicpc.net/problem/1157

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net


문제

  • 알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

입력

  • 첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.

출력

  • 첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

입출력 예제


알파벳 26개를 의미하는 배열과 아스키코드 없이 풀어보려고 하루종일 매달리다 결국 못했다..

원래 풀려던 방식은 다음과 같다.

  • toCharArray(), toUpperCase(), 향상된 for문 등을 사용해서 문자열에서 중복 문자를 확인하고, 중복된 문자가 있으면 카운트를 증가시킨다.
  • 증가된 카운트가 동일한 문자가 있으면 '?' 를 리턴해준다.

하지만 시간이 너무 오래 지체되었으니 일단 다른 사람들이 푼 방식을 보고 결과를 내보기로 했다

조금 더 공부해서 다음에 다시 원하는 방식대로 풀어보기로 하자


풀이 방식을 정리해보자.

일단 main을 깨끗하게 만들기위해 최소한의 코드만 작성하고 나머지는 메소드에 넣어 작업했다.

메소드 구현으로 바로 넘어가보자.

 

1. 결과가 문자로 출력되어야 하므로 char형인 변수 result를 선언한다.

 

2. 최대 중복값인 max를 선언하고, -1로 초기화한다.

  • 만약 입력한 문자열 중에 해당하는 문자가 없다면 배열에 0이라는 값이 들어가게 되므로 -1로 초기화해야 안전하다. 

3.  알파벳의 개수인 26으로 cnt 배열을 선언한다.

 

4. 입력받은 문자열의 길이만큼 돌며 cnt 배열에 값을 넣어주는 for문을 작성한다.

  • 해당 알파벳의 숫자값을 구하기 위해 65를 뺀다. 이는 아스키코드와 관련이 있다.
  • 이를 통해 구해진 숫자값을 인덱스로 삼아서 해당 인덱스에 값을 더한다.

test를 예를 들어서 살펴보자.

필자는 System.out.println(str.charAt(i) + " " + (str.charAt(i) - 65)); 를 통해 각 값을 확인해보았다.

str.charAt(i) 은 각각 'T, E, S, T' 라는 값이 출력되었다.

str.charAt(i) - 65 은 각각 '19,  4, 18, 19' 라는 값이 출력되었다.

  • 결과적으로 cnt[19] 에는 '2' 라는 값이 저장되어있고, 나머지 4, 18 에는 1씩 저장되는 것이다.

5. 모든 알파벳만큼 돌며 결과를 추출하는 for문을 작성한다.

  • 첫 if문은 cnt[j]에 저장된 수가 max보다 크면 cnt[j]의 값을 max에 넣어주기 위해 작성한다. 또한 result 변수에 해당 인덱스 + 65를 통해 숫자값을 알파벳으로 변경하여 저장하도록 한다.
  • 동일하게 test를 예를 들어서 살펴보자.
  • A라는 알파벳은 cnt[0] 에 있고, cnt[0]의 값은 '0' 이다. 이 때 max는 '-1' 의 값을 가지고 있다.
  • 결과적으로 A의 경우 cnt[0]의 값이 크므로 max는 0이 된다.
  • B라는 알파벳은 cnt[1] 에 있고, A와 마찬가지로 값이 0이다. 그러면 cnt[1]과 max의 값이 동일하게 '0'이 된다.
  • 하지만 26번을 전부 돌아야하므로 다음 알파벳으로 넘어간다. 다 돌고나서 결과적으로 cnt[j]와 max 값을 비교하여 '?' 출력 여부를 확인한다.

수행 결과를 확인한다.

답안 소스

import java.util.Scanner;

public class Main {

	public static char countAlpha(String str) {
		char result = '?';
		int max = -1;
		int[] cnt = new int[26];
		
		for(int i=0; i<str.length(); i++) {
			cnt[str.charAt(i) - 65]++;
		}
		
		for(int j=0; j<cnt.length; j++) {
			if(cnt[j] > max) {
				max = cnt[j];
				result = (char)(j+65);
			}else if(cnt[j] == max) {
				result = '?';
			}
		}
		return result;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next().toUpperCase();
		
		System.out.println(countAlpha(str));
	}
}