백준 | 문자열 섹션 - 1157번 풀이

728x90

1157번. 단어 공부

문제

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

입력

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

출력

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

내 코드 (1차 시도: 메모리 초과)

  • 콘솔창에서는 모든 예제에 대한 결과 출력이 정상 작동했지만, 백준에 제출했을 때는 메모리 초과가 떴다.
  • 아마도 너무 복잡하게 풀어서 그런듯 하다 ^^ ..ㅎㅎ

내 시도 = 문자열 들어오면 앞 문자 뽑고 뒷 문자열들 내부를 for로 돌면서 앞에서 뽑아놓은 문자와 동일한 문자 발견할 때마다 카운팅을하고 그 값을 cnt[] 배열에 세팅해주는 것이었다.

오히려 복잡한 접근이었다. 왜냐면 그냥 처음부터 cnt[]를 알파벳 개수만큼 세팅해주면서 해당 알파벳의 인덱스 값안에 들어온 문자열의 문자를 각각 카운팅해줬다면 더 쉽게 풀렸을 것이다.

import java.util.Scanner;

public class Main {
    //솔루션 함수 
    public String solution(String str) {
        String answer = "";
        int[] cnt = new int[str.length()]; //카운팅용 배열 
        int p = 0;

        str.toUpperCase(); //대소문자 구분X -> 통일시킴

        for(int i = 0; i<str.length(); i++) {
            char x = str.charAt(i); //현재 i의 문자 뽑고 
            String tmp = str.substring(1); //하나씩 자른 뒷 문자열 

            for(int j = 0; j<tmp.length(); j++) {
                if(x == tmp.charAt(j)) {
                    p++;
                }
                cnt[j] = p;
            }
        }

        int m = 0;
        for(int i = 0; i<cnt.length-1; i++) {
            if(cnt[i] <= cnt[i+1]) {
                if( m == cnt[i+1]) {
                    return "?";
                }else if(m < cnt[i+1]) {
                    m = cnt[i+1]; //최대로 갱신 
                    char tmp = str.charAt(i);
                    answer = String.valueOf(tmp);
                }
            }    
        }
        return answer.toUpperCase();
    }

    //실행 메인
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main T = new Main();
        Scanner kb = new Scanner(System.in);
        //1) 입력
        String str = kb.next();

        //2) 출력 
        System.out.println(T.solution(str));

    }
}

수정한 코드

  • 애초에 전체 알파벳 크기로 cnt[] 배열 만든 뒤
  • for문 돌면서 받은 문자열의 각 문자값에 해당하는 알파벳 idx 값의 cnt[] 배열에 값 ++
  • max 값 찾아가되, 더 큰 max 발견 시, 답에 해당 알파벳 문자를 세팅해주고 같으면 ? 세팅한다.
import java.util.Scanner;

public class Main {
    //솔루션 함수 
    public String solution(String str) {
        String answer = "";

        //방식 : A ~ Z 까지 담을 배열에 넣고 
        // 받은 문자열 내부에 해당하는 문자에 카운팅한다.
        int[] cnt = new int[26]; //카운팅용 배열 

        for(int i =0; i<str.length(); i++) {
            //뽑으 각 문자의 인덱스 가져오기 위해 
            int tmp = str.charAt(i) - 65; 
            //해당 문자 인덱스의 배열 상에 카운팅 ++ 한다 발견할때마다.
            cnt[tmp]++;
        }

        int max = 0;
        for(int i = 0; i<cnt.length; i++) {
            if(cnt[i]>max) {
                max = cnt[i];
                char tmp = (char) (i+65);//문자로 뽑기
                answer = String.valueOf(tmp); //답에 넣기 
            }else if(cnt[i] == max) { //max 동일하면 그냥 ? 출력
                answer = "?"; 
            }
        }
        return answer;
    }

    //실행 메인
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Main T = new Main();
        Scanner kb = new Scanner(System.in);
        //1) 입력
        String str = kb.next().toUpperCase();//대소문자 구분 X

        //2) 출력 
        System.out.println(T.solution(str));

    }
}
728x90