81301. 숫자 문자열과 영단어
2022-05-01
프로그래머스 81301번 풀이
이 글은 Obsidian에서 마이그레이션되었으며, 그 과정에서 AI의 도움을 받았습니다. 오류나 누락된 내용이 있다면 댓글로 알려주세요!
문제
코딩테스트 연습 - 숫자 문자열과 영단어 | 프로그래머스 스쿨
풀이
아이디어
숫자가 있는 부분은 그대로 넣어주고, 문자가 있는 부분은 문자 부분대로 잘라서 숫자로 변환해서 넣어주면 된다.
문제는 문자 부분을 어디까지 잘라야 하는지인데… 숫자가 등장할 때 까지 포인터를 옮기자니 seveneight 같은 경우에는 자르기가 곤란하다.
그래서 문자가 시작하는 시점부터, 영단어에 대응되는 숫자를 저장해둔 map digit_list에 해당하는 key가 있을 때 까지 반복해서 포인터를 옮겨주는 방법을 사용하기로 했다.
이렇게 해서 문제를 풀긴 했는데 풀고 나서 다른 분들의 코드를 구경하다가 regex라는 것을 발견하고 좀 찾아봤더니 정규 표현식을 지원하는 라이브러리였다…
regex 라이브러리의 regex_replace 함수를 사용하면 원하는 패턴의 문자열을 치환할 수 있다.
#include <regex>
#include <string>
...
s = regex_replace(s, regex("zero"), "0");
...
answer = stoi(s);
return (answer);이러면 지정한 패턴에 맞게 s에 치환이 된다. 이 문제에서는 영단어들 중에서 어떤 단어에 포함되는 그런 영단어가 없어서 이런 식으로 풀어도 되나? 하고 생각했는데 또 생각해보니까 순서만 잘 조정해주면 포함되는 관계에 있는 패턴이라도 잘 치환이 될 것 같다.
우와… 정규식을 사용할 수 있다는 것이 엄청 유용할 것 같아서 좀 더 자세히 읽어봐야겠다. (참고: 씹어먹는 C++ - <17 - 2. C++ 정규 표현식() 라이브러리 소개>)
코드
#include <string>
#include <vector>
#include <map>
using namespace std;
int solution(string s) {
int answer = 0;
map<string, int> digit_list = {{"zero", 0}, {"one", 1}, {"two", 2}, {"three", 3}, {"four", 4}, {"five", 5}, {"six", 6}, {"seven", 7}, {"eight", 8}, {"nine", 9}};
int idx = 0, len = s.length();
int start;
string str;
while (idx < len)
{
if (s[idx] >= '0' && s[idx] <= '9')
{
answer = answer * 10 + (s[idx] - '0');
idx++;
continue;
}
start = idx;
idx++;
while (idx < s.length() && (s[idx] >= 'a' && s[idx] <= 'z'))
{
idx++;
str = s.substr(start, idx - start + 1);
if (digit_list.find(str) != digit_list.end())
{
answer = answer * 10 + digit_list[str];
break;
}
}
idx++;
}
return answer;
}