알고리즘 - 문제 해결법
문제 해결을 위한 접근 방법
Intro
I. 문제 이해하기
문제를 완벽하게 이해해야 합니다. 문는 어떤 입력값을 가지며 어떤 출력값이 나와야하는지 분명히 하고 난 이후에 문제를 풀이해야합니다. 이를 위해선 질문도 서슴치 않아야합니다.
II. 구체적 예시 알아보기
예로, 문자의 수를 반환하는 문제를 해결해야 할 경우, 숫자 문자열은 포함하지 않는지 대 소문자 중복이 허용되는지, 인자로 빈 문자열이 들어갈 수 있는지 구체적 예시를 알아야합니다.
III. 문제 세분화하기
이전 과정에서 문자의 경우 모두 소문자로 변경하고 문자만 포함한다고 할 경우 문제를 주석으로 세분화 할 필요가 있습니다. 문제를 끝내지 못하더라도 세분화하면 문제를 이해하고 있다는 것을 증명할 수 있죠.
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
// 문자를 순회
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
// 공백 마침표 숫자라면 패스
// 리턴
}
IV. 쉬운 부분부터 시작하기
문제 해결시 복잡한 로직보다 이전 과정을 먼저 수행하는 것이 좋습니다.
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
const result = {};
// 문자를 순회
for (let i = 0; i < str.length; i++) {
var char = str[i];
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
if (result[char] > 0) {
result[char]++;
} else {
result[char] = 1;
}
// 공백 마침표 숫자라면 패스
}
// 리턴
return result;
}
이제 함수는 문자별 카운트 정보를 가진 객체를 반환합니다.
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
const result = {};
// 문자를 순회
for (let i = 0; i < str.length; i++) {
var char = str[i].toLowerCase();
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
if (result[char] > 0) {
result[char]++;
} else {
result[char] = 1;
}
// 공백 마침표 숫자라면 패스
}
// 리턴
return result;
}
이제 소문자로 변환할 수 있습니다. 이제 정규식을 추가해보면 될 것 같군요
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
const result = {};
// 문자를 순회
for (let i = 0; i < str.length; i++) {
var char = str[i].toLowerCase();
if (!/[a-z]/.test(char)) {
continue;
}
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
if (result[char] > 0) {
result[char]++;
} else {
result[char] = 1;
}
// 공백 마침표 숫자라면 패스
}
// 리턴
return result;
}
V. 문제를 다시 보고 리펙토링하기
문제를 해결했다면 시간 복잡도와 공간 복잡도를 생각하고 더 나은 성능을 위해 리펙토링해야합니다.
일단 for 문을 통해 숫자를 증가하고 각 인덱스에 접근하고 있습니다. 이 부분은 문자를 바로 반환받는 for...of
로 개선할 필요가 있습니다.
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
const result = {};
// 문자를 순회
for (let char of str) {
var char = char.toLowerCase();
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
if (/[a-z]/.test(char)) {
result[char] = ++result[char] || 1;
}
// 공백 마침표 숫자라면 패스
}
// 리턴
return result;
}
정규식은 간편히 사용할 수 있지만 직접 비교할 수 있다면 더 빠른 속도를 가진 방법도 있을겁니다.
js
charCount("Your PIN number is 1234!");
function charCount(str) {
// 반환값은 문자별 카운트를 한 객체가 반환
const result = {};
// 문자를 순회
for (let char of str) {
var char = char.toLowerCase();
// 문자가 숫자/문자이며(공백X) 이미 존재하는 프로퍼티의 경우 +1, 없다면 프로퍼티를 새로 추가하고 값으로 1
if (isAlpha(char)) {
result[char] = ++result[char] || 1;
}
// 공백 마침표 숫자라면 패스
}
// 리턴
return result;
}
function isAlpha(char){
const code = char.charCodeAt(0); // 해당 문자의 코드 넘버를 반환
if (!(code > 64 && code < 91) && // [A-Z]
!(code > 96 && code < 123)) { // [a-z]
return false;
}
return true;
}