Seren dev's blog
article thumbnail

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

 

1283번: 단축키 지정

첫째 줄에 옵션의 개수 N(1 ≤ N ≤ 30)이 주어진다. 둘째 줄부터 N+1번째 줄까지 각 줄에 옵션을 나타내는 문자열이 입력되는데 하나의 옵션은 5개 이하의 단어로 표현되며, 각 단어 역시 10개 이하

www.acmicpc.net

 

풀이

1. 옵션이 입력될 때마다 아래의 로직대로 단축키를 찾는다.

1-1. split으로 단어들을 저장하여 각 단어의 첫글자가 단축키로 지정될 수 있는지 확인한다.

1-2. 2번에서 단축키를 구하지 못했다면 옵션에서 각 단어의 첫글자를 제외하고, 왼쪽에서 차례대로 글자들을 보면서 단축키가 가능한 글자를 찾는다.

1-3. 어떠한 것도 단축키로 지정할 수 없으면 옵션 그대로의 문자열을 반환한다.

2. 단축키가 지정된 상태의 문자열을 출력한다. 

 

해당 알파벳이 단축키로 지정되어있는지 체크하기 위해 boolean[] isCheck 배열을 선언하고 크기는 26으로 지정한다.

코드

1-1번의 경우, 1-2번의 경우 각각 단축키가 지정된 상태의 문자열을 생성하는 방법이 다르기 때문에 오버로딩을 통해 함수를 구현했다.

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

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        boolean[] isCheck = new boolean[26];

        StringBuilder sb = new StringBuilder();

        for (int t = 0; t < n; t++) {
            String option = br.readLine();
            String str = findRepresentativeKey(option, isCheck);

            sb.append(str).append("\n");
        }

        System.out.println(sb);
    }

    static String findRepresentativeKey(String option, boolean[] isCheck) {
        // 1. 단어의 첫 글자가 이미 단축키로 지정되었는지 살펴본다.
        String[] words = option.split(" ");
        for (int wordIdx = 0; wordIdx < words.length; wordIdx++) {

            char alphabet = words[wordIdx].charAt(0);

            if (alphabet >= 'A' && alphabet <= 'Z') {
                alphabet = (char)('a' + (alphabet - 'A'));
            }
            int num = alphabet - 'a';

            if (!isCheck[num]) {
                isCheck[num] = true;
                String key = makeKey(words, wordIdx);
                return key;
            }
        }

        // 2. 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.
        for (int i = 1; i < option.length(); i++) {
            if (option.charAt(i) == ' ') {
                i += 1;
                continue;
            }

            char alphabet = option.charAt(i);

            if (alphabet >= 'A' && alphabet <= 'Z') {
                alphabet = (char)('a' + (alphabet - 'A'));
            }
            int num = alphabet - 'a';

            if (!isCheck[num]) {
                isCheck[num] = true;
                String key = makeKey(option, i);
                return key;
            }
        }

        // 3. 어떠한 것도 단축키로 지정할 수 없다면 문자열 그대로 반환한다..
        return option;
    }

    // wordIdx번째의 단어의 첫글자가 단축키로 지정된 경우
    static String makeKey(String[] words, int wordIdx) {
        int idx = 0;
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < words.length; i++) {
            String word = words[i];
            if (i == wordIdx) {
                sb.append("[").append(word.charAt(0)).append("]");
                sb.append(word.substring(1)).append(" ");
            }
            else {
                sb.append(words[i]).append(" ");
            }
        }
        return sb.toString();
    }

    // option의 idx번째 글자가 단축키로 지정된 경우
    static String makeKey(String option, int idx) {
        StringBuilder sb = new StringBuilder();
        sb.append(option, 0, idx);
        sb.append("[").append(option.charAt(idx)).append("]");
        sb.append(option.substring(idx+1));

        return sb.toString();
    }
}

 

 

다른 풀이

각 단어의 첫글자가 단축키로 지정될 수 있는지 확인할 때, 

option.split(" ")으로 단어들을 저장할 필요 없이 while문을 사용하여 각 단어의 첫글자를 확인한다.

즉, 단축키가 지정된 상태의 문자열을 만들 때 makeKey(String, int) 함수만을 사용한다.

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

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        boolean[] isCheck = new boolean[26];

        StringBuilder sb = new StringBuilder();

        for (int t = 0; t < n; t++) {
            String option = br.readLine();
            String str = findRepresentativeKey(option, isCheck);

            sb.append(str).append("\n");
        }

        System.out.println(sb);
    }

    static String findRepresentativeKey(String option, boolean[] isCheck) {
        // 1. 단어의 첫 글자가 이미 단축키로 지정되었는지 살펴본다.
        for (int i = 0; i < option.length(); i++) {
            char alphabet = option.charAt(i);

            if (alphabet >= 'A' && alphabet <= 'Z') {
                alphabet = (char)('a' + (alphabet - 'A'));
            }
            int num = alphabet - 'a';

            if (!isCheck[num]) {
                isCheck[num] = true;
                String key = makeKey(option, i);
                return key;
            }

            while (true) {
                i++;
                if (i >= option.length() || option.charAt(i) == ' ') break;
            }
        }

        // 2. 왼쪽에서부터 차례대로 알파벳을 보면서 단축키로 지정 안 된 것이 있다면 단축키로 지정한다.
        for (int i = 1; i < option.length(); i++) {
            if (option.charAt(i) == ' ') {
                i += 1;
                continue;
            }

            char alphabet = option.charAt(i);

            if (alphabet >= 'A' && alphabet <= 'Z') {
                alphabet = (char)('a' + (alphabet - 'A'));
            }
            int num = alphabet - 'a';

            if (!isCheck[num]) {
                isCheck[num] = true;
                String key = makeKey(option, i);
                return key;
            }
        }

        // 3. 어떠한 것도 단축키로 지정할 수 없다면 문자열 그대로 반환한다..
        return option;
    }

    // option의 idx번째 글자가 단축키로 지정된 경우
    static String makeKey(String option, int idx) {
        StringBuilder sb = new StringBuilder();
        sb.append(option, 0, idx);
        sb.append("[").append(option.charAt(idx)).append("]");
        sb.append(option.substring(idx+1));

        return sb.toString();
    }
}

 

 

1번째가 다른 풀이, 3번째가 원래 풀이다. 근소한 메모리 차이가 있다.

 

728x90
profile

Seren dev's blog

@Seren dev

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!