[백준] 1181번 단어정렬
- 알고리즘/백준
- 2020. 4. 15. 12:28
반응형
반응형
문제
알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.
- 길이가 짧은 것부터
- 길이가 같으면 사전 순으로
입력
첫째 줄에 단어의 개수 N이 주어진다. (1≤N≤20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.
출력
조건에 따라 정렬하여 단어들을 출력한다. 단, 같은 단어가 여러 번 입력된 경우에는 한 번씩만 출력한다.
이 문제는 조건이 너무 많다. 그것들을 전부 신경쎠줘야 하기 떄문에 생각보다 까다로운 문제였다.
#include <bits/stdc++.h>
using namespace std;
bool compre(const string a , const string b) {
if (a.length() < b.length()) {
return true;
} else if (a.length() == b.length()) {
for(int i = 0; i < a.length();i++) {
if (a[i] == b[i]) {
continue;
}
return a[i] < b[i];
}
}
return false;
};
int main() {
int n;
cin >> n;
vector<string> words;
for(int i = 0; i< n;i++) {
string word;
cin >> word;
words.push_back(word);
}
sort(words.begin(),words.end(),compre);
words.erase(unique(words.begin(),words.end()),words.end());
for(int i = 0; i<words.size();i++) {
cout << words[i] << "\n";
}
}
비교 조건은 string a와 string b가 길이가 긴쪽이 먼저 작성되지만
만약, 길이가 같은 경우라면 사전순으로 정렬해야한다.
그런데 이 사전순이라는게 앞자리만 바꾼다고 되는게 아니다.
앞자리가 바뀌면 뒷자리도 확인시켜줘야 한다.
그래서 if (같다면) 계속 하라는 코드를 추가해주었다. 그래야 순차적으로 동작할거라 생각했다.
마지막으로 중복을 지우기 위해 erase라는 걸 사용했다.
배열이니 set이니 방법은 여러개가 있을 수 있겠지만 찾다보니 vector을 활용해서 사용하는 것을 찾았다.
그러면 결과가 정상적으로 나온다.
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
string word[20002];
bool cmp(string a, string b){
if(a.length() < b.length())
return true;
if(a.length() > b.length())
return false;
return a.compare(b) < 0;
}
int main(void){
int N;
scanf("%d", &N);
for(int i = 0; i < N; i++){
char tmp[101];
scanf("%s", tmp);
word[i] = tmp;
}
sort(word, word+N, cmp);
for(int i = 0; i < N; i++){
if(i > 0 && word[i] == word[i-1])
continue;
cout << word[i] << endl;
}
}
아니 이런 방법이? 아 이런식으로도 할 수 있겠구만...
반응형
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 2193번 이친수 (0) | 2020.04.16 |
---|---|
[백준] 2156번 포도주 시식 (0) | 2020.04.15 |
[백준] 1463번 1로 만들기 (0) | 2020.04.14 |
[백준] 1021번 회전하는 큐 (0) | 2020.04.12 |
[백준] 9012번 괄호 (0) | 2020.04.11 |