네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.
다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.
- 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 |