ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준/BOJ] 1157번 : 단어 공부 (JAVA / 자바)
    백준 2022. 2. 14. 16:04

    안녕하세요~ 코딩하는 코알못 코메인입니다.

     

     

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

     

    1157번: 단어 공부

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

    www.acmicpc.net


    - 문제 -

     

    난이도 브론즈 1 문제이다.

    자바에서 입력방식은 scanner와 bufferedreader가 있다.

    자바를 초반에 접하면 처음에 배우는 입력은 scanner이다. scanner가 bufferedreader보다 편하지만 속도가 느리다.

    bufferedreader는 무조건 문자열로 받아오기때문에 정수형이나 실수형 변수에 저장하기 위해서는 입력과 형변환을 해줘야한다.

    더 자세한 내용은 아래 글 참고 하면 좋다.

    https://comain.tistory.com/3

     

    (JAVA / 자바) Scanner 와 Bufferedreader

    안녕하세요~ 코딩하는 코알못 코메인입니다. 이번엔 백준 문제 풀면서 계속 언급될 scanner와 bufferedreader에 대한 간단한 정리를 해볼거다. 자바에서 입력은 scanner와 bufferedreader가 있다. 우선 각자

    comain.tistory.com

     

    풀이 방법

    문자열을 입력을 받고, 문자열의 0인덱스에 있는 값을 문자열에서 제외해준다. 그렇게 하면 제외 전과 후의 길이의 차이가 생길 것이고, 그 차이가 곧 0인덱스에 있던 값의 총 갯수가 된다.

    이렇게 하기 전에 우선 봐야 할 것이 있다. 입력값이 소문자와 대문자가 둘다 존재 할 수 있다는 것이다. 그렇게 되면 z를 지우려 하면 Z는 지워지지 않는다. 그리고 출력할때의 값은 대문자로 출력해야하기때문에 입력값을 문자열에 저장할 때 전부 다 대문자로 바꿔서 저장 해준다. String.toUpperCase를 사용하자.

    그렇게 바꿧으면 먼저 말한대로 0인덱스 값을 지워줘야하는데 지우기 전 문자열의 길이와 0인덱스 값이 필요하다. 지워버린 후에는 0인덱스 값과 길이가 변하기 때문에 지우기 전 값을 변수를 선언해서 저장해 준다.

    저장 한 후에 지워주는데 지우는데는 String.replace를 사용하자.

     

    두 지우기 전 후 길이의 값의 차. 즉 0인덱스 값(알파벳)의 중복된 값의 개수(중복개수라고 하겠다.)가 여태 중복개수의 최대값보다 크다면 최대값 저장 변수에 저장을 해주고, 중복개수가 제일 많은 알파벳을 출력하기위해 만들어둔 문자열 변수에 저장한다. 하지만 만약 최댓값이 현재 중복개수와 같다면 문자열 변수에 더해준다.

    예로 들어보자. 예제 1번의 Mississipi. 대문자로 바꾸면 MISSISSIPI처음의 M을 없애면 ISSISSIPI가 되고 두 길이의 차이는 1이기때문에 M의 개수는 1개이다. 이전 중복개수의 최댓값은 0개이니 이번에 1개이기 때문에 문자열 변수에 M을 저장한다. 다음 0인덱스 값인 I를 없애면 SSSSP가된다. 두 길이의 차이는 4이니 I의 개수는 4개이다. 이전 중복개수의 최댓값은 1개이니 이번에 4개이기 때문에 문자열 변수에 I를 저장한다. 그렇게되면 현재 문자열 변수의 값은 I이다. 그리고 다음 0인덱스 값인 S를 지우면 P가 남는다. 두 길이의 차이는 4이니 S의 개수는 4개이다. 그럼 이전 최댓값과 같으니 문자열 변수에 S를 더한다. 그러면 문자열 변수의 값은 PS가 된다.

    이렇게 중복개수가 같으면 문자열 변수에 쌓아가고, 더 크면 문자열 변수의 값을 초기화 시키고 새로 저장한다.

    그렇게 반복문을 처음 입력값이 빌때까지 진행하고 종료한다.

    반복문이 종료되면 문자열 변수에 알파벳이 1개가 들어있는지 아닌지를 판단하고 1개일 경우 문자열 변수를 출력, 2개 이상일 경우 ?를 출력한다.

    코드를 보자.

     


    -풀이-

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		//입력값을 대문자로 바꿔 저장
    		String S = br.readLine().toUpperCase();
    		//알파벳 중복 개수의 최댓값을 저장할 변수
    		int max = 0;
    		//중복개수가 최댓값인 알파벳을 저장 할 변수
    		String result = "";
    		
    		//무한루프(알파벳의 개수는 26개이기때문에 26번 반복하는 반복문을 만들어도 된다.)
    		while(true) {
    			//현재 문자열의 0 인덱스 값을 저장
    			String index = String.valueOf(S.charAt(0));
    			//현재 문자열의 길이를 저장
    			int size = S.length();
    			//0인덱스 값을 문자열에서 제외
    			S = S.replace(String.valueOf(S.charAt(0)), "");
    			//제외한 후의 문자열의 길이
    			int newsize = S.length();
    			
    			//두 길이의 차가 중복개수
    			//중복개수가 최댓값과 같으면 result에 알파벳을 더한다.
    			if(max == (size - newsize)) {
    				result += index;
    			}
    			//중복개수가 최댓값보다 크면 최댓값에 중복개수를 저장하고, result에 알파벳을 저장.
    			if(max < (size - newsize)) {
    				max = (size - newsize);
    				result = index;
    			}
    			//문자열이 비게되면 무한루프 종료
    			if(S.equals("")) break;
    		}
    		//result에 알팦벳이 1개이면 result 출력.
    		//아니면 ?출력
    		if(result.length() == 1) {
    			System.out.println(result);
    		}else {
    			System.out.println("?");
    		}
    	}
    
    }

     

    주석을 좀 많이 달게되어 주석 없는 것도 올려드립니다.

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		String S = br.readLine().toUpperCase();
    		int max = 0;
    		String result = "";
    		
    		while(true) {
    			String index = String.valueOf(S.charAt(0));
    			int size = S.length();
    			S = S.replace(String.valueOf(S.charAt(0)), "");
    			int newsize = S.length();
    			
    			if(max == (size - newsize)) {
    				result += index;
    			}
                
    			if(max < (size - newsize)) {
    				max = (size - newsize);
    				result = index;
    			}
                
    			if(S.equals("")) break;
    		}
    		
    		if(result.length() == 1) {
    			System.out.println(result);
    		}else {
    			System.out.println("?");
    		}
    	}
    
    }

    -결과-

     


    아직 코딩 공부가 부족한 필자라 설명과 풀이 방법이 많이 미흡할 수 있다. 코딩 고수분들은 보시고 문제점이 있다면 댓글로 말해주시면 감사한 마음으로 참고 수정 하겠습니다.

    댓글