Notice
Recent Posts
Recent Comments
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
관리 메뉴

일상

[c++] 백준 2914: 크로아티아 알파벳 본문

programming

[c++] 백준 2914: 크로아티아 알파벳

Mysteryu 2023. 6. 7. 22:15

푸는데 시간이 꽤 걸린 예제라서 관련 포스팅을 진행하려고 한다. 처음 제출 코드는 아래와 같다

 

#include <iostream>

/*
c=  
c-  
dz= 
d-  
lj  
nj  
s=  
z=  

c : 99
= : 61
- : 45
d : 100
z : 122
l : 108
j : 106
n : 110
s : 115
z : 122

앞에 나오는 알파벳
c : -, =   case 1
d : z, -, z=  case 2
z : =      case 3
l : j      case 4
n : j      case 5
s : =      case 6

*/

int main() {
	std::string s;
	std::cin >> s;

	int i = 0;
	int count = 0;
	while (i < s.length() - 1) {
		if (int(s[i]) == 99) { //case1 : c
			if (int(s[i + 1]) == 61) { // c=
				i += 2;
				++count;
			}
			else if (s[i + 1] == 45) { // c-
				i += 2;
				++count;
			}
			else {// c
				++i;
				++count;
			}
		}
		else if (int(s[i] == 100)) { //case2 : d
			if (int(s[i + 1]) == 122 && int(s[i + 2]) == 61) { //dz=
				i += 3;
				++count;
			
			}
			else if (s[i + 1] == 45) { // d-
				i += 2;
				++count;
			}
			else {
				++i;
				++count;
			}
		}
		else if (int(s[i] == 122)) { //case3
			if (int(s[i + 1]) == 61) { // z=
				i += 2;
				++count;
			}
			else {// z
				++i;
				++count;
			}
		}
		else if (int(s[i] == 108)) { //case 4
			if (int(s[i + 1]) == 106) { // lj
				i += 2;
				++count;
			}
			else {// l
				++i;
				++count;
			}
		}
		else if (int(s[i] == 110)) { //case 5
			if (int(s[i + 1]) == 106) { // nj
				i += 2;
				++count;
			}
			else {// l
				++i;
				++count;
			}
		}
		else if (int(s[i] == 115)) { //case6
			if (int(s[i + 1]) == 61) { // s=
				i += 2;
				++count;
			}
			else {// l
				++count;
				++i;
			}
		}
		else {
			++i;
			++count;
		}

	}

	if (i == s.length() - 1) { // 반복문의 마지막 비교 문자가 그냥 알파벳일 경우 
		count++;
	}
	std::cout << count << "\n";
}

소스의 의도를 설명하면 반복문을 통하여 문자열의 개별 문자에 대해 조건에 대한 검사를 진행한다. 이때 변수 i는 해당 문자의 index를 나타낸다. 만약 그 문자를 시작으로 크로아티아 알파벳이 나열된다면 굳이 바로 다음 문자에 대해 검사를 할 필요가 없으므로 변수 i를 해당 크로아티아 알파벳의 길이만큼 더해준다. 

 

반복문을 빠져나오는 조건으로는 i < s.length() -1 로 해주었는데 최대 크로아티아 알파벳의 길이는 3이고 마지막-1 번째 문자열에서 길이 3의 문자에 대해 검사를 진행할 수 있기 때문이다(문자열의 마지막 문자는 null 이므로). 루프를 빠져나온 이후 한번  더 검사를 진행하는데 만약 i가 s.length() -1일 경우에는 마지막 검사 문자가 크로아티아 알파벳을 이루는 문자가 아니므로 문자열의 마지막 문자(null 제외)가 그냥 알파벳이기 때문에 알파벳의 개수에 1을 더해주면 된다.

 

사실 코드도 그렇고 설명도 그렇고 그리 직관적이지 못한 것 같아서 다른 분들은 어떻게 제출했나 블로그를 둘러보던 중 string의 find와 replace를 사용하여 문제를 해결하는 포스팅을 보았고 참고하여 다시 제출하였다. 

 

관련 티스토리 : [C++ 백준] 2941 크로아티아 알파벳 (tistory.com)

 

#include <iostream>
#include <string>

int main() {

	std::string s;
	std::cin >> s;

	std::string arr[8] = { "c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=" };
	for (int i = 0; i < 8; i++) {
		while (true) {
			if (s.find(arr[i]) != std::string::npos) {
				int index = s.find(arr[i]);
				s.replace(index, arr[i].length(), "a");
			}
			else
				break;
		}
	}

	std::cout << s.length() << "\n";
}

지금 코드가 이전 코드보다는 훨씬 직관적인 것을 볼 수 있다. 반복문 안에서 while문을 쓰는 이유는 중복된 크로아티아 알파벳이 있을 수 있기 때문이다. STL 사용을 최대한 자제하려고 생각했는데 생각을 조금 바꿔서 STL을 활용한 예와 활용하지 않은 예를 모두 구현해본다면 도움이 꽤 될거라고 생각이 되었다.

'programming' 카테고리의 다른 글

[C++] 백준 2563 : 색종이  (0) 2023.06.21
[C++] 백준 10798: 세로 읽기  (0) 2023.06.20
[c++] 백준 1316: 그룹 단어 체커  (0) 2023.06.06
[c++] 백준 2444  (0) 2023.05.31
[c++] 백준 1157  (0) 2023.05.30
Comments