문제 풀이/[JAVA_자바] 백준

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

Seunghyun_KO 2021. 12. 13. 23:00
728x90
반응형

문제

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


입력

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


출력

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


 


문제 접근 방법

한 단어가 입력될 때 대소문자가 섞여있다. 이를 if조건문으로 일일이 구분해서 계산해줘도 좋지만 편의를 위해 나는 모두 대문자로 전환하여 빈도수를 측정해줬다. 이때, 알파벳의 빈도수를 체크할 때는 알파벳이 총 26자이므로 26개만큼의 int형 배열을 선언해주어 A는 0번 부터해서 Z는 25번까지 각각 알파벳에 번호를 임의로 지정해 주었다. 그래서 해당 알파벳이 나올 때마다 각각의 알파벳에 해당하는 인덱스의 저장된 값의 수를 1씩 증가시켜주어 빈도수를 측정해주고 해당 작업이 끝나면 반복문을 한번 더 돌려주어 어느 알파벳이 가장 많이 나왔는지 체크를 해준다. 이때 최빈값(가장 많이 사용된 알파벳)이 2 이상이면 "?"를 출력해야 하기 때문에 ascii코드를 참고하여 -2를 출력할 변수에 저장해주고 아니면 해당 알파벳에 전에 임의로 부여한 인덱스를 저장해 주어 마지막에 출력해주면 끝난다.


JAVA 코드 풀이

import java.util.*;

public class Main{
    public static void main(String args[]){
        Scanner input = new Scanner(System.in);
        int apb[] = new int[26]; // A~Z까지 0~25에 각각 나온 횟수를 저장할 배열 초기화
        String str = input.next(); // 단어 입력
        str = str.toUpperCase(); // 단어가 대소문자 섞여서 입력되므로 대문자로 모두 전환(소문자로 전환해도 무관)
        for(int i=0; i<str.length(); i++){
            apb[str.charAt(i)-'A']++; // 나온 단어에 해당하는 인덱스의 정수 값을 1씩 증가시킨다
        }
        int max = 0, ans=0;
        for(int i=0; i<apb.length; i++){
            if(max < apb[i]){ // 지금까지 나온 최빈값이랑 현재 인덱스의 저장된 값이랑 비교(가장 많이 사용된 알파벳 찾는 조건문)
                max = apb[i];
                ans = i;
            }
            else if(max == apb[i]){ // 지금까지 나온 최빈값이랑 현재 인덱스의 저장된 값이 같은지 확인(최빈값이 2 이상이면 "?"출력해야함)
                ans = -2; // ascii코드에서 ?는 A보다 2가 작기 때문
            }
        }
        System.out.printf("%s", Character.toString(ans+'A')); // 결과값 출력
    }
}

코드 실행 결과


후기

해당 문제는 알파벳 출현 빈도수를 어떻게 저장할지 캐치하는 게 포인트인 문제인 것 같다. ascii코드를 알고 있다면 보다 편하게 문제를 풀 수 있었으리라 생각된다. 생각보다 char관련 변수나 함수를 사용할 때 ascii코드를 사용하는 문제들이 많은 만큼 ascii코드에서 자주 쓰이는 'a'~'z', 'A'~'Z'의 ascii넘버는 외워두면 시간 단축에 도움이 될 것으로 보인다.

+ 위 방법 말고 그냥 입력받은 단어 그대로 대문자는 -'A'를 해주고 소문자는 -'a'를 해서 빈도수 측정하는 방법이 메모리적인 측면이나 시간적인 측면이나 효율적인 것으로 결과로 보였다. 따라서 나중에 단어의 입력이 많아지면 toUpperCase함수를 호출하는 것보다 대소문자를 구분해서 조건문으로 해결하는 게 효율적인 코드가 될 수 있을 것 같다는 생각이 든다.

import java.util.*;

public class Main{
    public static void main(String args[]){
        Scanner input = new Scanner(System.in);
        int apb[] = new int[26];
        String str = input.next();
        int cont, temp;
        String ans;
        for(int i=0; i<str.length(); i++){
            temp = str.charAt(i);
            if(temp >= 'a')
                cont = 'a';
            else
                cont = 'A';
            apb[temp-cont]++;
        }
        int max = 0, idx=0;
        for(int i=0; i<apb.length; i++){
            if(max < apb[i]){
                max = apb[i];
                idx = i;
            }
            else if(max == apb[i]){
                idx = -2;
            }
        }
        System.out.printf("%s", Character.toString(idx+'A'));
    }
}

입력받는 단어가 단 하나인데도 이러한 차이를 보인다

 


문제 원본

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

728x90
반응형