1. 문자열 내 마음대로 정렬하기(https://school.programmers.co.kr/learn/courses/30/lessons/12915)
문제를 요약하자면, 문자열의 인덱스 n번째 글자를 기준으로 문자열을 오름차순 정렬하는 것이다. 이때, 만약 n번째 글자가 같다면 해당 문자열은 사전순으로 정렬한다.
해서, 내가 맨 처음 사용한 방법은 다음과 같다.
- 문자열을 사전 순으로 정렬
- 반복문을 돌려 i번째 문자열과 i + 1 번째 문자열의 인덱스 n을 비교
- 만약 i번째 문자열의 인덱스 n 쪽이 i + 1 번째 문자열의 인덱스 n 보다 크다면 swap()을 사용해 서로 교환
- 2 ~ 3 을 계속 반복
- i + 1 이 문자열 개수 만큼 오면 반복문 종료
while(1)
{
if(answer[i][n] > answer[i + 1][n] && i + 1 <= strings.size() - 1)
{
answer[i].swap(answer[i + 1]);
}
i++;
if(i + 1 == strings.size())
break;
}
하지만 이렇게 되면 작은 문제가 있다.
반복문 특성상 이미 한 번 지났던 부분은 다시 돌아갈 수 없는데, 그렇게 되면 앞 부분에 아직 정렬이 덜 끝난 상태가 될 수 있다. 글로는 설명을 다 못하여 간단한 예시를 들자면, 다음과 같다.
- 3 2 1 // 초기 상태. 첫번째와 두번째 값을 비교
- 2 3 1 // 비교 후 교환 완료. 두번째와 세번째 비교
- 2 1 3 // 반복문 끝
반복문에서 i는 계속 더해지고 있다. 그래서 문자열은 첫번째와 두번째, 두번째와 세번째, 세번째와 네번째, i번째와 i+1번째를 비교하는 형식이다.
하지만 이렇게 되면 예시처럼 제대로 된 정렬이 되지 않는다.
그래서 나는 i + 1이 마지막에 도달하면 다시 i를 초기화 시켜주기로 했다. 하지만 이렇게 되면 계속 반복될 뿐이다. 이를 해결하기 위해 나는 교환이 일어날 때마다 changeCount를 더해주기로 했다. changeCount != 0은 정렬이 1번 이상은 일어났다는 소리고, changeCount = 0은 더이상 정렬이 일어나지 않았다는 소리다. 즉, 이미 정렬된 상태라는 뜻이다.
하여, 최종적인 코드는 다음과 같다.
// c++ 첫번째 방법
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<string> solution(vector<string> strings, int n) {
vector<string> answer = strings;
int i=0;
int changeCount = 0;
sort(answer.begin(),answer.end());
while(1)
{
if(answer[i][n] > answer[i + 1][n] && i + 1 <= strings.size() - 1)
{
answer[i].swap(answer[i + 1]);
changeCount++;
}
i++;
if(i + 1 == strings.size() && changeCount != 0)
{
i = 0;
changeCount = 0;
}
else if(i + 1 == strings.size() && changeCount == 0) // 정렬이 일어나지 않았다는 건 이미 정렬이 끝났다는 소리다.
break;
}
return answer;
}
다음은 조금 더 간단한 방법이다. 문자열 맨 앞에 문자열 n번째 인덱스에 있는 문자를 붙인다. 그 다음 사전 순으로 정렬을 하고, 맨 앞에 붙였던 문자를 제거한다.
// c++ 두번째 방법
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<string> solution(vector<string> strings, int n) {
vector<string> answer = strings;
for(int i=0; i<strings.size(); i++)
{
// n번째 글자를 맨 앞에 붙인다.
answer[i] = answer[i][n] + answer[i];
}
sort(answer.begin(),answer.end()); // 사전 순으로 정렬
for(int i=0; i<strings.size(); i++)
{
// 맨 앞에 있던 문자를 제거한다.
answer[i].erase(answer[i].begin());
}
return answer;
}
JS 도 C++ 두번째 방법과 같은 방법을 사용했다.
// js
function solution(strings, n) {
var answer = strings;
for(var i=0; i<answer.length; i++){
answer[i] = answer[i][n] + answer[i];
}
answer.sort();
for(var i=0; i<answer.length; i++){
answer[i] = answer[i].replace(answer[i][0], "");
}
return answer;
}
'프로그래머스' 카테고리의 다른 글
24/08/09 - 명예의 전당(1), 2016년(C++, JS) (0) | 2024.08.09 |
---|---|
24/08/05 - K번째수, 두 개 뽑아서 더하기, 가장 가까운 같은 글자(C++, JS) (0) | 2024.08.05 |
24/08/01 - 숫자 문자열과 영단어(C언어, js) (0) | 2024.08.01 |
24/07/31 알고리즘 문제 (0) | 2024.07.31 |
24/07/30 알고리즘 문제 (0) | 2024.07.30 |