본문 바로가기

개발/DS&Algorithms

[백준] 알파벳 찾기_10809_자바

반응형

10809번 Java - 알파벳 찾기


이번 문제는 <문자열> 입니다.

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

 

10809번: 알파벳 찾기

각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다. 만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출

www.acmicpc.net


1. 문제

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오.

* 마치 영어를 번역한 듯한 난해한 문장의 문제입니다. 뒤에서 예제 입력과 출력을 보면 이해가 바로 되실 겁니다.

2. 예제


3. 풀이

예제에서 봤듯이 어떠한 단어를 입력하면, 그 단어에 해당하는 알파벳이 단어에서 몇 번째 위치에 있는지 찾는 문제입니다. 여기서 주의할 점은 위 예제에서 처럼 o와 같이 중복 알파벳이 나왔을 때는 가장 앞에 있는 알파벳의 위치로 출력합니다. 또한 해당되지 않은 알파벳은 -1로 출력합니다.

이번 문제도 Scanner와 BufferedReader 두 가지를 통해서 입력을 받을 수 있습니다. 여기서 입력되는 방법만 다를 뿐 풀이 원리는 비슷하기 때문에 BufferedReader만 이용해서 풀이를 하도록 하겠습니다.


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));
        
        int[] arr = new int[26] // 알파벳 개수만큼 int 배열을 생성
        
        for(int i=0; i<arr.length; i++) {
        	arr[i] = -1;	// 배열 내부 -1로 초기화
        }
        
        String S = br.nextLine(); // 단어 입력
        
        for(int i=0; i<S.length; i++) {
        	
            char ch = S.charAt(i); // 입력받은 단어의 각 자리에 해당하는 알파벳 추출
            
            if(arr[ch - 'a'] == -1) { // 이 전에 동일한 알파벳을 찾았는지 여부 체크
            	arr[ch - 'a'] = i // 아스키 코드로 알파벳의 위치에 해당하는 배열에 i 값 대입
            }
        }
        
        for(int result:arr) {	//향상된 for문을 통해서 배열 전체 출력
         System.out.print(result + " "); // 알파벳 간 공백으로 구분
        }
    
    }
}

1) 여기서 알아야할 부분은 '아스키 코드' 입니다.

위 코드에서 단어내의 알파벳을 출력 후에 아스키(ASCII)코드를 활용하여 arr 배열과 연결시키고 있는 것을 알 수 있습니다.

단어에서 추출한 알파벳의 위치를 배열에 넣는 과정

이 부분을 자세하게 보도록 하겠습니다.

S는 입력한 단어가 들어있는 문자열 변수입니다. 이 안에서 단어에 길이만큼 반복을 하면서 단어의 알파벳을 하나씩 출력합니다. 이때 charAt(int index) 메소드를 활용합니다.

다음 if문의 조건을 보면, arr[ch - 'a'] == -1 이 보입니다. ch는 단어의 i번째에 해당하는 알파벳입니다. 'a'는 소문자 a를 아스키 코드값으로 나타냅니다. 참고로 소문자 a의 아스키 코드값은 97입니다. 즉, ch의 아스키 코드값에서 97을 뺀 값이 배열의 인덱스로 들어가게 됩니다. 예를 들어서 i가 0이라면 ch는 b에 해당합니다. b의 아스키 코드값은 98이기 때문에 arr[98 -97]로 arr[1]이 됩니다. 다시 조건으로 돌아가서 arr[1]의 값이 -1인지 판단하는 것입니다. 만약 입력한 단어에서 이전에 b가 있었다면 배열에는 -1이 아니었을 것입니다.

이 조건에서 true라면 동일하게 arr[ch - 'a']에 값을 i로 넣어줍니다. 이유는 i가 알파벳이 단어에서 몇 번째에 위치하는지 알려주는 것이기 때문입니다.

소문자 알파벳의 아스킷 코드값은 97부터 122에 해당합니다.

아스키 코드표 예시

2) 출력은 배열에서 처음부터 끝까지 get(i)를 진행하면 됩니다. 여기서 자바의 향상된 for문을 활용할 수 있습니다.

for(대입 받을 변수 형식 : 배열명) { }

추가로 문제에서

문제 출력 예시

이 같이 공백으로 구분하라고 했기 때문에

자바에서는 System.out.println이 아닌 System.out.print(String + " ") 로 작성해줍니다.


4. 결론

 


추가로..

indexOf()을 활용할 수도 있습니다.

indexOf() : 문자열 내에서 특정한 문자열의 index 값을 리턴
import java.util.Scanner;

public class Main {  
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.next();

        for (char c = 'a' ; c <= 'z' ; c++)
            System.out.print(input.indexOf(c) + " ");
    }
}

//indexOf는 해당 문자가 문자열에 없으면 -1을 리턴
반응형