문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/17682#
2018 KAKAO BLIND RECRUITMENT에 나온 문제이라 여기에 정보가 자세히 나와있다.
문자열 처리 (String Manipulation)를 묻는 문제
앞에서부터 한 글자씩 잘라서 처리할 수 있고, 또는 간단한 컴파일러를 만들듯이 토큰화 (Tokenizing)와 의미 분석 (Semantic Analysis)을 통해 어렵지 않게 계산할 수 있다.
점수 중에는 한 자리뿐만 아니라 두 자리인 10점도 포함되어 있기 때문에 한 글자씩 잘라서 처리할때는 그 부분에 유의할 것!
이 문제의 정답률은73.47%
가독성 위해 vsc 캡처


두번째 다시 푸는건데 regex 문법은 솔루션 참고했다.
근데 점점 이해하는 속도는 빨라진 것 같아서 기분이 좋다.
내 생각:
1. reduce 메서드는 O(n)이고 그 안에서 문자열 길이만큼 split 메서드로 처리할 때 시간복잡도가 최고로 높다고 판단했다.
2. split 메서드가 처리하는 문자열은 문제조건을 봤을 때 사실상 상수 값으로 봐도 무관하다. ("점수|보너스|[옵션]"으로 이루어진 문자열 3세트, 최소 6글자 ~ 최대 12글자)
3. 따라서 내 코드의 시간복잡도는 O(n)이다.
https://stackoverflow.com/questions/33483793/big-o-of-javascript-built-in-split-function
const solution = (dartResult) => {
const bonusTable = {
S: 1,
D: 2,
T: 3,
};
const optionTable = {
"*": 2,
"#": -1,
"": 1,
};
const resultsArray = dartResult.match(/([0-9]|10)[SDT]{1}[*|#]?/g); // ['1S', '2D*', '3T']
const scores = resultsArray.reduce((acc, cur) => {
const eachResult = cur.split(/([SDT]{1})/g);
const [score, bonus, option] = eachResult; // ["1", "S", ""]
if (option === "*") {
acc[acc.length - 1] *= 2;
}
acc.push(score ** bonusTable[bonus] * optionTable[option]);
return acc;
}, []);
const answer = scores.reduce((acc, cur) => acc + cur);
return answer;
};
regex에 좀만 더 익숙해지면 좋겠다.
다른 사람 정규식 보니까 0-10 범위를 \d{1,} 이렇게 하던데
주어진 범위 외 숫자도 들어가니까 오류 처리를 못할 것 같아서 구글링해서 /([0-9]|10)[SDT]{1}[*|#]?/g 으로 리팩토링했다.
(split() Regex를 이용해 구분자도 결과에 포함하기 )
separator가 포획 괄호 () 를 포함하는 정규표현식일 경우, 포획된 결과도 배열에 포함
자세히 보기
console.log("abcSdefDghiT".split(/([SDT]{1})/));
// 출력: ['abc', 'S', 'def', 'D', 'ghi', 'T', '']
const myString = 'Hello 1 word. Sentence number 2.';
const splits = myString.split(/(\d)/);
console.log(splits);
// 출력: [ "Hello ", "1", " word. Sentence number ", "2", "." ]