네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.

다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.

  • 1478 → "one4seveneight"
  • 234567 → "23four5six7"
  • 10203 → "1zerotwozero3"

이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.

참고로 각 숫자에 대응되는 영단어는 다음 표와 같습니다.

숫자영단어

0 zero
1 one
2 two
3 three
4 four
5 five
6 six
7 seven
8 eight
9 nine

제한사항

  • 1 ≤ s의 길이 ≤ 50
  • s가 "zero" 또는 "0"으로 시작하는 경우는 주어지지 않습니다.
  • return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.

 

[ 나의 풀이 ]

 

import java.util.HashMap;
import java.util.Map;

public class NumberAndWord {
    public static void main(String[] args) {
        /*
        - 숫자놀이
        : 네오 -> 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면
        프로도는 원래 숫자를 찾는 게임

        //when
        네오가 프로도에게 일부 자릿수를 영단어로 바꾼 카드를 건네줌

        //then
        프로도는 원래 숫자를 찾음

        // how
        1. hashMap 에 0 ~ 9 까지 저장
        2. 입력받은 문자열을 char 형으로 변환
        3. 변환된 char 형이 문자일 경우 하나씩 합치면서 hash value 값과 동일한지 비교
         ( 숫자일 경우 결과 값에 바로 합쳐줌 )
        4. 비교 후 같으면 해당 값을 hashMap 가 비교해서 같은 값을 가지는 key 값을
           결과 값에 합쳐줌
        */
        int res = solution("one4seveneight");
        System.out.println(res);
    }

    public static int solution(String s){
        int answer = 0;
        String temp = "";


        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(0, "zero");
        hashMap.put(1, "one");
        hashMap.put(2, "two");
        hashMap.put(3, "three");
        hashMap.put(4, "four");
        hashMap.put(5, "five");
        hashMap.put(6, "six");
        hashMap.put(7, "seven");
        hashMap.put(8, "eight");
        hashMap.put(9, "nine");

        //when
        char[] ch = s.toCharArray();

        for (int i = 0; i < ch.length; i++) {
            int k = Character.getNumericValue(ch[i]);
            if(0 <= k && k <= 9){
                if(answer == 0){
                    answer += k;
                }
                else{
                    answer = (answer * 10) + k;
                }
            }
            else {
                temp += ch[i];
                for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
                    if (entry.getValue().equals(temp)) {
                        if (answer == 0) {
                            answer += entry.getKey();
                        } else {
                            answer = (answer * 10) + entry.getKey();
                        }
                        temp = "";
                    }
                }
            }
        }

        return answer;
    }
}

 

다른 사람의 코드를 보니 너무 깔끔하고 짧게 구현해놔서 제 코드를 다시 보니 부끄럽네요..

 

import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;
        StringBuilder sb = new StringBuilder("");
        int len = s.length();
        String[] digits = {"0","1","2","3","4","5","6","7","8","9"};
        String[] alphabets = {"zero","one","two","three","four","five","six","seven","eight","nine"};

        for(int i=0; i<10; i++){
            s = s.replaceAll(alphabets[i],digits[i]);
        }

        return Integer.parseInt(s);
    }
}

모르겠는 메소드와 타입이 있어서 분석 먼저 해보겠습니다.

 

StringBuilder

변경 가능한 문자열을 만들어줍니다.

 

 

아래와 같이 String 형을 그냥 더하게 된다면 메모리 할당과 해제를 시키는 면에서 비효율적인 코드가 완성됩니다.

String a = "aa";
String b = "bb";
String c = a+b;

 

자바에서 String 형은 변경이 불가능합니다.

 

[ 문자열이 더해지는 과정 ]

1) 하나의 문자열을 다른 문자열과 연결하면 새 문자열이 생성

2) 이전 문자열은 가비지 컬렉터로 들어갑니다.

 

만약, 이러한 행위를 100만번을 하게 된다면 많은 메모리를 잡아 먹게 됩니다.

이 경우 사용하는게 StringBuilder 입니다.

 

 

[ 사용 방법 ]

1) StringBuilder 객체 생성

2) append 로 더해줌

3) toString() 으로 할당

StringBuilder sb = new StringBuilder();
sb.append("aa").append("bb");
String c = sb.toString();

 

 

replaceAll
  • replace ( 변환하고자 하는 대상 문자열 , 변환할 문자 )
String str = "aaaa";
System.out.prinln(str.replace("aa","bbb");

// 결과값 : bbbbbb
  • replaceAll ( 변환하고자 하는 대상 문자열, 변환할 문자 )
String str = "jajavava";
System.out.println("java","cool");

// jacoolva 출력

이렇게 보면 차이가 없어 보이지만 중요한 차이점은 지금부터 입니다.

 

String random = "AbCdGgZz";
System.out.println(random.replaceAll("[bdz]",Y);

// AYCYGgZY 출력

b,d,z 라는 값을 모두 Y로 바꿔주겠다는 의미입니다.

 

그러면 위의 코드가 이해가 됩니다.

 

[ 동작과정 ]

1. 알파벳 배열의 값들이 옴

2. 해당 알파벳 배열 값을 찾은 인덱스와 동일한 위치의 digit 배열로 대체

'프로그래머스' 카테고리의 다른 글

신규 아이디 추천 ( replaceAll, 정규표현식 )  (0) 2022.08.18
신고 결과 받기  (0) 2022.08.11
폰켓몬  (0) 2021.07.31
체육복  (0) 2021.07.31
로또 최고 순위와 최저 순위  (0) 2021.07.30

+ Recent posts