렝무식

[프로그래머스 81301번] 숫자 문자열과 영단어 (JAVA) 본문

Algorithm/Programmers

[프로그래머스 81301번] 숫자 문자열과 영단어 (JAVA)

렝9 2023. 1. 13. 16:03

Programmers - [81301] 숫자 문자열과 영단어


image

🖍 숫자와 영단어가 혼합된 문자열을 모두 숫자로 변환하여 반환하는 문제

(link) 81301 (2021 카카오 채용연계형 인턴십) 숫자 문자열과 영단어 (Lv.1)


[풀이 과정]

내가 푼 방법이 효율적이지 않다는 점을 감안하고 시작한다.

결론부터 말하자면 s를 모두 숫자로 변환한 뒤 StringBuilder에 문자열 형태로 저장해둔 후 int 데이터로 변환하여 반환할 것이다. 풀이의 핵심이 되는 메소드는 바로 ArrayList의 indexOf() 메소드이다.

 

우선 크기가 10인 String 배열 arr를 선언하여 zero 부터 nine까지 채워준다.
이때 각 단어가 들어간 인덱스는 해당 영단어가 뜻하는 숫자와 일치하게 된다.
indexOf()를 사용하기 위해 Arrays.asList(arr)를 이용하여 리스트로 전환시킨다. 이렇게 되면 그 다음부터는 간단하다.

 

문자열 s에서 charAt(0)을 통해 첫 글자가 숫자인지 알파벳인지 판별한다.

(Character.isDigit() 메소드로 char 변수에 들어간 문자가 숫자인지 아닌지 판별이 가능하다.

문제 풀 당시에 해당 메소드를 몰랐어서 아래 코드에서는 조건으로 아스키 코드 값을 비교했다.)

 

1. 첫 글자가 숫자이면 StringBuilder에 substring(0,1)값을 넣어준다. 그리고 문자열 s를 substring(1)으로 초기화해주어 문자열 맨 앞 한 글자를 삭제한다.

 

더보기

<참고: substring() 메소드>

substring()의 인자로 숫자 한 개가 들어오면 해당 인덱스부터 끝까지의 문자를 반환한다.
ex) s = "one" 일 때
s.substring(1) = "ne"

 

숫자 두 개가 들어오면 첫 번째 인자의 인덱스부터 두 번째 인자의 인덱스-1까지를 반환한다.
ex) s = "three" 일 때
s.substring(0,3) = "thr"

 

2. 첫 글자가 알파벳일 경우는 다음과 같이 한다.

 

i=3부터 시작하여 5까지 반복하는 for문을 이용하여substring(0,i) 으로 s의 글자 세 개 부터 해서 5개까지 확인한다.
(이 때 3부터 5까지 확인하는 이유는 zero~nine 영어의 철자 중에서 알파벳 세 개 미만인 영단어가 없고, 다섯 개를 넘는 영단어가 없기 때문이다)

 

그렇게 철자 3개부터 시작하여 단어를 뽑아내서 문자열 변수에 저장하고 array.indexOf()를 이용해 해당 단어가 리스트 내부에 있는지 확인한다.

리스트 내부에 있다면 해당 인덱스를 StringBuilder에 저장하고 substring(i)로 s를 초기화한다.

그렇지 않다면 continue를 이용하여 철자 4개, 철자 5개를 차례대로 확인한다.

 

더보기

<참고>

indexOf() 메소드는 리스트에 같은 값이 있으면 해당 인덱스를 반환하고 그렇지 않으면 -1을 반환한다.

 

문자열 s를 확인하는 작업이 끝나면 StringBuilder에 들어간 문자들을 toString()으로 문자열 변수로 변환한 뒤 Integer.parseInt()를 통해 숫자로 변환한다.
(사실 값을 출력하기만 하면 정수로 변환하는 것은 필수가 아니지만, 프로그래머스 문제의 경우 반환값을 정수형으로 받아야 하기 때문에 변환해준다)


[Pseudocode]

int solution(String s)
1. int answer 선언
2. StringBuilder sb 선언
3. 배열 arr에 "zero ~ nine" 채우기
4. arr를 배열리스트 array로 변환
5. while s가 빌 때까지 반복
    6. if s.charAt(0)이 숫자일 때
        7. sb에 s의 첫 글자 저장
        8. s에서 s의 첫 글자 삭제
    9. else (알파벳일 때)
        10. for i=3 부터 5까지 반복
            11. 문자열 str에 0부터 i까지의 문자열을 잘라 저장
            12. if array 안에 str라는 문자가 없다면
                13. continue
            14. else (있다면)
            15. sb에 해당 인덱스 저장
            16. s에서 str만큼 삭제
            17. break;
18. answer에 sb를 int데이터로 변환하여 저장
19. return answer

[Code]

main함수는 테스트케이스를 시험해보려고 편의상 작성하였다.

프로그래머스는 solution 메소드만 작성하면 된다.

import java.util.*;

/**
 * 프로그래머스 81301번
 * 숫자 문자열과 영단어
 * 
 */
public class Problem15 {
    public static void main(String[] args) {
        String str = "one4seveneight"; // 테스트 케이스 입력
        System.out.println(solution(str));
    }

    public static int solution(String s) {
        int answer = 0; // 반환값
        StringBuilder sb = new StringBuilder(); // 반환값 저장
        String[] arr = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}; // 각 문자 저장
        ArrayList<String> array = new ArrayList<>(Arrays.asList(arr)); // 리스트 전환

        while (!s.equals("")) {
            char c = s.charAt(0);
            if(48 <= c && c <= 57) { // 만난 문자가 숫자일때
                sb.append(s.substring(0,1));
                s = s.substring(1);
            }

            else { // 만난 문자가 알파벳일때
                for(int i=3 ; i<=5 ; i++) {
                    String str = s.substring(0,i);
                    if(array.indexOf(str) == -1)
                        continue;
                    else {
                        sb.append(array.indexOf(str));
                        s = s.substring(i);
                        break;
                    }
                }
            }
        }

        answer = Integer.parseInt(sb.toString());

        return answer;
    }
}

[Result]

image


(2021.07.28 풀이분)

Comments