알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.
1. 길이가 짧은 것부터
2. 길이가 같으면 사전 순으로
첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.
조건에 따라 정렬하여 단어들을 출력한다. 단, 같은 단어가 여러 번 입력된 경우에는 한 번씩만 출력한다.
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(void) {
cin.tie(NULL); ios::sync_with_stdio(false);
vector<vector<string>> arr(50);
string input;
int i, j, N;
cin >> N;
for (i = 0; i < N; i++) {
cin >> input;
arr[input.length()-1].push_back(input);
}
for (i = 0; i < 50; i++) {
if (arr[i].size() > 0) {
sort(arr[i].begin(), arr[i].end());
arr[i].erase(unique(arr[i].begin(), arr[i].end()), arr[i].end());
for (j = 0; j < arr[i].size(); j++) { cout << arr[i][j] << endl; }
}
}
return 0;
}
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct Word {
char str[51];
int len;
unsigned long hash;
Word() {len = 0; hash = 0;}
Word(const char st[51]) {
hash = 5381;
len = 0;
do {
// 간단한 해시를 이용해 같은 문자열인지 비교
hash = 33 * hash + (unsigned char)st[len];
str[len] = st[len];
} while (st[len++] != '\0');
}
};
bool compare(Word& w1, Word& w2) {
// strick weak odering
// a == b 일 때 a > b, a < b 가 다 false 를 반환함
if (w1.len == w2.len)
{
for (int i = 0; i < w1.len; ++i)
{
if (w1.str[i] != w2.str[i])
return w1.str[i] < w2.str[i];
}
return false;
}
return w1.len < w2.len;
}
int main() {
vector<Word> vs;
char str[52];
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%s", str);
vs.push_back(Word(str));
}
sort(vs.begin(), vs.end(), compare);
for(int i = 1; i < vs.size(); ++i) {
// 해시값이 같으면 같은 문자열로 취급
if(vs[i].hash != vs[i - 1].hash)
printf("%s\n", vs[i - 1].str);
}
// 마지막 문자열은 무조건 출력하도록
printf("%s\n", vs[n - 1].str);
return 0;
}