문제 설명
네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를
건네주면 프로도는 원래 숫자를 찾는 게임입니다.
다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.
- 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로 주어집니다.
입출력 예
"one4seveneight" | 1478 |
"23four5six7" | 234567 |
"2three45sixseven" | 234567 |
"123" | 123 |
입출력 예 설명
입출력 예 #1
- 문제 예시와 같습니다.
입출력 예 #2
- 문제 예시와 같습니다.
입출력 예 #3
- "three"는 3, "six"는 6, "seven"은 7에 대응되기 때문에 정답은 입출력 예 #2와 같은 234567이 됩니다.
- 입출력 예 #2와 #3과 같이 같은 정답을 가리키는 문자열이 여러 가지가 나올 수 있습니다.
입출력 예 #4
- s에는 영단어로 바뀐 부분이 없습니다.
제한시간 안내
- 정확성 테스트 : 10초
<cpp>
#include <iostream>
#include <string>
#include <regex>
#include <vector>
using namespace std;
int solution(string s) {
int answer = 0;
string arr[10] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
for(int i=0; i<10; i++) {
s = regex_replace(s, regex(arr[i]), to_string(i));
}
answer = stoi(s);
return answer;
}
replace라는 함수는 원래 알고있었지만, 사용법에 대해 까먹어서 replace 함수를 찾아보던중 regex를 알게되었다.
regex는 정규표현식을 이용해 문자열을 다룰때 유용한 stl이라고 한다.
regex_replace에 대해 설명하자면,
regex_replace(바꿀 문자열이 들어있는 전체 문자열, 정규표현식 무엇을, 무엇으로 바꿀것인지) 라고 보면된다.
매개변수 각각의 type은 string, regex, string이다.
위의 코드로 보자면, 입력이 들어온 문자열 s에서 arr[i]를 찾아 i로 바꿔주는것이다.
예시로 3을 바꾸려고 한다면, s에서 arr[3]="three"를 찾아 to_string(3)인 "3"으로 바꿔주는 것이다.
여기서 가운데 매개변수가 regex형인데, 무엇을 바꿀것인지를 ""안에 정규표현식을 직접 써주어도 된다.
그리고 나서 return type이 int이므로 stoi함수를 통해 string을 int로 바꿔주었다.
처음에 반복문에 for(int i=0; i<11; i++) { ... } 라고 적어주어 abort : core dumped라는 오류가 났다.
찾아보니 잘못된 인덱스를 참조할 경우 생길 수 있는 오류였다.
배열이 10까지 있는데 10에서 i++를 할경우 11이되어 참조오류가 났던것이다.
이런 기초적인 실수를 조심해야겠다.
<js>
function solution(s) {
let answer = s;
let nums = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
for(let i=0; i<nums.length; i++) {
let arr = answer.split(nums[i]);
answer = arr.join(i);
}
return Number(answer);
}
정규표현식을 사용해 replace로 하나하나씩 대응되는 값을 집어넣을까,
아니면 object를 만들어서 key, value쌍으로 대응되는 값을 저장해놓은 후에 마찬가지로 대응되는 값에 대해 처리를 할까 고민했다.
물론 위와같이 해도 잘 돌아가지만 적어놓은 위 방법이 간결하고 제일 맘에드는 풀이이다.
일단 "zero"부터 "nine"까지 저장해준다.
그리고나서 반복문을 이용해서 순회를 하면서 nums 배열의 원소에 해당하는 값을 기준으로 잘라준다.
여기서 중요한 점은 nums의 인덱스가 그에 해당하는 뜻이라는것이다.
nums[0] = "zero", nums[1] = "one", ... nums[9] = "nine"
그러면 그 기준 문자열을 기준으로 잘려서 앞뒤가 저장된다.
예를들어 1two3가 있다면, "two"를 기준으로 앞뒤가 잘려 arr엔 "1"과 "3"이 저장된다.
"two"를 찾아서 잘랐을 경우, 반복문의 i는 2이다.
따라서 잘라진 두 문자열을 i를 이용해 join 해주면 "123"이 될것이다. (문자열임에 주의!)
하지만 문제에서 원하는 return 값은 숫자이기 때문에 Number()를 이용해서 숫자로 바꿔주면 된다.
'PS > Programmers' 카테고리의 다른 글
Programmers / Level1 / 크레인 인형뽑기 / C++ / JS (0) | 2021.10.14 |
---|---|
Programmers / Level1 / 신규 아이디 추천 / C++ / JS (0) | 2021.10.09 |
Programmers / Level1 / 로또의 최고 순위와 최저 순위 / C++ (0) | 2021.10.07 |
Programmers / Level1 / 완주하지 못한 선수 / C++ (0) | 2021.09.28 |