알고리즘 : C++/BaekJoon

백준 2870번 - 수학 숙제

동 노이만 2023. 5. 23. 12:37

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;
}