이번 글에서는 문자열을 인자로 받아 해당 문자열이 알파벳 순서(오름차순 또는 내림차순)로 정렬되어 있는지 판별하는 JavaScript 함수를 작성해 보겠습니다.
요구 사항
작성할 함수는 다음과 같이 동작해야 합니다.
isSorted('adefgjmxz') // true → 오름차순으로 정렬됨
isSorted('zxmfdba') // true → 내림차순으로 정렬됨
isSorted('dsfdsfva') // false → 오름차순과 내림차순이 뒤섞임구현 코드
핵심 아이디어는 인접한 두 문자의 charCodeAt() 값 차이를 비교하는 것입니다. 한 단계라도 증가했다면 'u', 감소했다면 'd'를 기록하고, 두 표식이 모두 나타나면 그 문자열은 정렬된 상태가 아닌 것으로 판단합니다.
const str = 'abdfhlmxz';
const findDiff = (a, b) => a.charCodeAt(0) - b.charCodeAt(0);
const isStringSorted = (str = '') => {
if (str.length < 2) {
return true;
}
let res = '';
for (let i = 0; i < str.length - 1; i++) {
if (findDiff(str[i + 1], str[i]) > 0) {
res += 'u';
} else if (findDiff(str[i + 1], str[i]) < 0) {
res += 'd';
}
if (res.includes('u') && res.includes('d')) {
return false;
}
}
return true;
};
console.log(isStringSorted(str));
코드 설명
- findDiff(a, b): 두 문자의 유니코드 코드 값 차이를 반환하여 대소 관계를 판별합니다.
- 뒤 문자가 앞 문자보다 크면 'u'(증가), 작으면 'd'(감소)를 결과 문자열에 누적합니다.
- 'u'와 'd'가 동시에 존재하면 오름차순도 내림차순도 아니므로 즉시 false를 반환합니다.
- 길이가 2 미만인 문자열은 비교 대상이 없으므로 항상 정렬된 것으로 간주합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
true
더 간결한 대안: every() 활용
배열 메서드 every()를 사용하면 동일한 로직을 더 직관적이고 짧은 코드로 표현할 수 있습니다.
const isSorted = (str = '') => {
const chars = [...str];
const asc = chars.every((c, i) => i === 0 || c >= chars[i - 1]);
const desc = chars.every((c, i) => i === 0 || c <= chars[i - 1]);
return asc || desc;
};
console.log(isSorted('abdfhlmxz')); // true
console.log(isSorted('zxmfdba')); // true
console.log(isSorted('dsfdsfva')); // false두 방법 모두 시간 복잡도는 O(n)으로 문자열을 한 번만 순회하므로 효율적입니다. 상황에 맞는 방식을 선택해 사용하시면 됩니다.