BOJ

[백준 1157번/JAVA] 단어 공부

syj0522 2024. 3. 11. 20:35

문제

백준 1157번
알파벳 대소문자로 이루어진 단어를 입력받고, 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 대소문자를 구분하지 않는다.
만약 가장 많이 사용된 알파벳이 2개 이상이면 ?를 출력한다. 

풀이 1)

배열을 어떻게 사용해야할지 떠오르지 않아서 HashMap을 사용했는데 시간초과가 나왔다.
아직 해시맵이 익숙하지 않아서 삽입, maxValue 찾는 방법, maxValue의 key 출력하는 방법을 서치하며 구현했는데 몇 개의 예제를 입력해본 결과 IDE에서는 맞게 실행되는 것 같다.

코드

//HashMap 사용, 시간초과

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args)throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        HashMap<String, Integer> map = new HashMap<>();
        //단어에서 가장 많이 쓰인 알파벳 찾아 대문자로 출력, 여러 개이면 ? 출력
        //대소문자 구분 x

        //문자열 입력받고 모두 대문자로 변환
        //하나씩 비교하면서 몇 개 있는지 세기, HashMap에 key value로 저장
        //Collections.max(map.values())로 최댓값 찾기, key 출력
        //최댓값이 여러갠지 for문 돌면서 확인 후 여러개면 ? 출력

        String str = br.readLine().toUpperCase();
        for(int i=0; i<str.length(); i++) {
            int count = 0;
            for(int j=0; j<str.length(); j++) {
                if(str.charAt(i) == str.charAt(j)) {
                    count++;
                }
            }
            map.put(String.valueOf(str.charAt(i)), count);
        }
        int maxValue = Collections.max(map.values());
        int sameLetterExists = 0;
        for(Map.Entry<String, Integer> entry : map.entrySet()) {
            if(maxValue == entry.getValue()) {
                sameLetterExists++;
            }
        }
        if(sameLetterExists>1) {
            bw.write("?");
        }else {
            for(Map.Entry<String, Integer> entry : map.entrySet()) {
                if(maxValue == entry.getValue()) {
                    bw.write(entry.getKey());                    
                }
            }
        }
        bw.close();
    }
}

풀이 2)

문자열을 입력받는다.

 

대소문자 상관없이 판단해야 하므로 toUpperCase()를 사용하여 문자열을 모두 대문자로 변경한다.

알파벳이 각각 몇 개씩 있는지 저장할 배열을 선언한다. 알파벳은 26자이므로 크기가 26인 배열 선언

 

arr[0]에 A가 몇 개 있는지 저장, arr[1]에 B가 몇 개 있는지 저장 ... -> arr.length번 반복 (바깥 for문)
해당 알파벳이 문자열에 몇 개 있는지 확인 -> word.length()번 반복 (안쪽 for문)

 

대문자 A는 유니코드로 65이므로 추출한 문자와 ((char)(65+i)) 를 비교

 

먼저 최댓값을 찾고 그 값이 몇 번 등장했는지 확인

 

최댓값이 두 개 이상이면 '?'를 출력, 한 개면 알파벳 출력

코드

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args)throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        //문자열 받고 모두 대문자로 변환
        //A~Z까지에 해당하는 크기가 26인 배열 생성, 모두 0으로 초기화
        //charAt()으로 문자 추출하여 알파벳이 있으면 각 배열의 값 1씩 증가시키기
        //유니코드로 대문자 A는 65
        //arr값 중 max값 찾기, max가 2개 이상이면 ? 출력 1개면 해당 알파벳 대문자 출력

        String word = br.readLine().toUpperCase();
        int[] arr = new int[26];

        for(int i=0; i<arr.length; i++) {
            arr[i] = 0;
            for(int j=0; j<word.length(); j++) {
                if(word.charAt(j) == (char)(65+i)) {
                    arr[i] += 1;
                }
            }
        }

        int max = 0;
        for(int k : arr) { //최댓값 찾기
            if(k > max) {
                max = k;                
            }
        }

        int count = 0;
        for(int k : arr) { //최댓값이 두 개 이상인지 찾기
            if(k == max) {
                count++;                
            }
        }

        if(count>1) {
            bw.write("?");
        } else {
            for(int i=0; i<arr.length; i++) {
                if(arr[i] == max) {
                    bw.write(String.valueOf((char)(65+i)));
                }
            }            
        }
        bw.close();
    }
}

Note

지난 번에 알파벳 갯수 세는 문제는 배열을 사용해서 잘 맞혔으면서 오늘은 왜 생각하지 못 했는지.. 요 며칠간 머리가 잘 안 돌아가는 느낌이다.