백준 2870번 - 수학 숙제
https://www.acmicpc.net/problem/2870
2870번: 수학숙제
종이에서 찾은 숫자의 개수를 M이라고 하면, 출력은 M줄로 이루어져야 한다. 각 줄에는 종이에서 찾은 숫자를 하나씩 출력해야 한다. 이때, 비내림차순으로 출력해야 한다. 비내림차순은 내림차
www.acmicpc.net
풀이 과정
문자열을 받고 숫자를 골라 오름차순으로 정렬 후 출력하는 문제이다. 단, 입력 문자열의 최대 길이가 100이므로 정수형으로 변환해서 하는 것이 아닌, 문자열 자체를 정수형으로 다듬고 대소를 비교해서 출력 해야한다. 문자열을 입력받고 _prev를 통해서 이전 값이 숫자이고 다음 값이 문자라면 token을 rez()에서 앞에 붙은 0을 제거해주고 ret에 넣었다. 만약 그게 아니고 s[i]가 숫자라면 token에 계속해서 더해줬다. 한 줄의 문자열 검사가 끝났을 때, 토큰에 남은 숫자가 있다면 rez() 처리를 해준 후, ret에 넣었다. 그리고 문자열 sort()를 위해서 cmp() 함수를 작성해줬고, 자릿수가 같을 경우 첫 자리부터 대소를 비교하고 이외의 경우 자릿수로 대소를 비교했다.
느낀 점
단순히 보고 접근했지만 생각보다 까다로웠다. 두 번째 푸는 문제임에도 입력이 100글자 까지라는 사실을 뒤늦게 알아서 한 번 헤맸다. 그리고 숫자 앞에 붙은 0을 제거할 때, 맨 뒤 숫자가 0이라면 0으로 반환 해버리는 잘못된 설계를 디버깅을 하며 찾아냈다. (0200 같이 0으로 끝나는 수를 0으로 반환) 항상 느끼지만 문자열은 꽤 섬세해서 문자열 관련 숙련도가 얼마나 있는지가 꽤 중요한 것 같다. 시간은 두 번째 푸는 것 치고 오래 걸렸지만 코드 자체는 이전 보다 깔끔히 짜여졌다고 생각한다.
#include<bits/stdc++.h>
using namespace std;
int n;
string temp;
vector<string> str, ret;
string number = "0123456789";
//문자열 숫자 비교 함수
bool cmp(string a, string b) {
if (a.size() == b.size()) {
for (int i = 0; i < a.size(); i++) {
if (a[i] != b[i]) return a[i] < b[i];
}
}
return a.size() < b.size();
}
//숫자 앞에 붙은 0을 제거, 혹은 0은 0으로
void rez(string* s) {
int idx = 0;
for (int i = 0; i < (*s).size(); i++) {
if ((*s)[i] != '0') break;
else (*s).erase(0, 1);
i = -1;
}
if ((*s).empty()) (*s) = "0";
return;
}
//문자열 한 줄에서 숫자를 찾아 vector<string> ret에 대입
void find_num(string s) {
string token = "";
bool flag = false;
char _prev = 'a';
for (int i = 0; i < s.size(); i++) {
if (number.find(_prev) != string::npos && number.find(s[i]) == string::npos) {
rez(&token);
ret.push_back(token);
token = "";
}
else if (number.find(s[i]) != string::npos) token += s[i];
_prev = s[i];
}
if (token != "") {
rez(&token);
ret.push_back(token);
}
return;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
//입력
cin >> n;
for (int i = 0; i < n; i++) {
cin >> temp;
str.push_back(temp);
}
//매 줄마다 문자열 검사
for (int i = 0; i < str.size(); i++) {
find_num(str[i]);
}
//문자열 숫자 정렬
sort(ret.begin(), ret.end(), cmp);
//출력
for (int i = 0; i < ret.size(); i++) {
cout << ret[i] << "\n";
}
return 0;
}