# 본인 풀이
#include<bits/stdc++.h>
using namespace std;
int n;
string s[100];
vector<string> ret;
vector<string> result;
bool cmp(string a, string b){
if(a.size() == b.size()){
for (int i = 0; i < a.size(); i++){
if((int)a[i] != (int)b[i]){
return (int)a[i] < (int)b[i];
}
continue;
}
// 그냥 삽입해둔 코드
return a.size() < b.size();
}
// 자릿수가 더 많은 문자열이 더 큰값
return a.size() < b.size();
}
// 반례?
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
// 앞자리 0으로 시작하는 애들은 atoi 호출시 자동으로 생략해줌.
for (int i = 0; i < n; i++){
cin >> s[i];
string t = "";
// s[i] 내에 간격을 두고 숫자가 두번 등장하는 경우?
int gap;
for (char chr : s[i]){
// 소문자 a ~ z 사이의 문자가 아니라면 무조건 숫자이므로 t에 푸시
if(gap > 1){
if(t.size()){
ret.push_back(t);
t = "";
gap = 0;
}
}
if ((int)chr < 97 || (int)chr > 122)
{
t += chr;
gap = 0;
}
gap++;
}
if(t.size()){
ret.push_back(t);
}
}
// 정렬은?
// sort(ret.begin(), ret.end());
for(string str : ret){
int idx = -1;
for (int i = 0; i < str.size(); i++){
if(str[i] != '0'){
break;
}
idx = i;
}
// 앞에 삽입된 0들 삭제
if(idx != -1){
str.erase(0, idx + 1);
if(str.size() == 0){
str = "0";
}
}
result.push_back(str);
}
sort(result.begin(), result.end(), cmp);
for(string str: result){
cout << str << "\n";
}
return 0;
}
문자를 숫자로 파싱할때 주의점
int
형 등으로 문자열을 파싱하게 되는데, 이때 문자열 길이에 주의해야한다. 문제 조건이 100글자까지 파싱 가능하도록 하였기때문에, 매우 큰 데이터를 다루는 자료형을 사용하지 않는 이상 문제는 오답처리됨!
ret
벡터에 각 입력되는 문자열들 중 숫자로 분리 가능한 부분을 추출하여 저장result
에 각 숫자들을 순회하며000..12
와 같이 앞자리가 0으로 시작하는 데이터들은 순수 숫자로 수정- sort 메서드에 분류기준 함수를 커스텀하여
cmp
에 구현. 문자열 길이가 더 길다는 의미는 자릿수가 많다는 의미이므로 -> 반드시 더 큼 - 문자열 사이즈가 동일한 경우 각 자리를 순회하며 더 큰 값을 리턴
# 모범 답안
#include<bits/stdc++.h>
using namespace std;
int n;
vector<string> v;
string s, ret;
void go(){
while(true){
// 0지우기
if(ret.size() && ret.front() == '0'){
ret.erase(ret.begin());
}else{
break;
}
}
// 다 지워버렸으면 해당 문자열은 0 -> 내 로직에도 포함되어 있음
if(ret.size() == 0){
ret = "0";
}
v.push_back(ret);
ret = "";
}
bool cmp(string a, string b){
// 사이즈 동일하면 -> 아스키코드 총합
if(a.size() == b.size()){
return a < b;
}
// 사이즈 다르면 -> 사이즈 큰애 리턴
return a.size() < b.size();
}
// 반례?
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
for (int i = 0; i < n; i++){
cin >> s;
ret = "";
for (int j = 0; j < s.size(); j++){
// 숫자들은 아스키코드 65밑에 깔려있음. 나머지 범위는 고려할 필요 X
// 숫자가 아닌 문자가 나타난 경우 -> 정제하러 go함수로 이동
if(s[j] < 65){
ret += s[j];
}else if(ret.size()){
go();
}
}
if(ret.size()){
go();
}
}
sort(v.begin(), v.end(), cmp);
for(string i: v){
cout << i << "\n";
}
return 0;
}
- 반례 고려는 잘 되었음.
- cmp 구현도 굿
- 사이즈 비교는 문자열 사전순 비교가 가능하므로 굳이 한글자씩 순회하며 int로 바꿔줄 필요가 없음!