Problem Solving/백준

[백준/c++] 10174 - 팰린드롬

세고래 2021. 3. 18. 06:16

www.acmicpc.net/problem/10174

 

10174번: 팰린드롬

팰린드롬은 앞으로 읽으나 뒤로 읽으나 똑같은 단어나 숫자들을 말한다. 일반적으로 대소문자를 구분하지 않지만, 공백은 구분한다. 다음은 팰린드롬의 예시이다. Anna Harrah Arora Nat tan 9998999 123

www.acmicpc.net


1) 풀이

입력받은 문자열을 맨앞과 맨뒤에서 차례대로 한글자씩 비교해보면 되는 문제이다.

직접 만든 이미지,, 잘 모르겠다면 댓글 남겨주세욥

이런식으로 문자열이 저장되어 있다고 생각하자.

칸은 각각의 문자가 들어있는 0부터 n-1까지의 인덱스로 정의할 수 있다. (string s. s[0], s[1]...)

처음에는 맨앞의 문자와 맨뒤의 문자 하나씩 비교를 한다. (반복문으로)

그 다음부터는 맨앞의 문자는 인덱스를 늘려가면서, 맨뒤의 문자는 인덱스를 줄여가면서 비교해주면 된다.

종료조건은 앞에 있던 문자의 인덱스가 뒤에 있던 문자의 인덱스보다 커졌을 때이다.

 

1) 일반적으로 대소문자를 구분한다 » toupper, tolower 함수를 이용하여 문자를 소문자, 대문자 중 하나로 통일하여 비교하며 된다.

2) 공백은 구분한다 » 공백을 받을 수 있는 getline 함수를 사용해야 한다!

 

※ tolower(c): 매개변수로 들어온 인자가 대문자인 경우, 소문자로 반환해준다

toupper(c): 매개변수로 들어온 인자가 소문자인 경우, 대문자로 반환해준다

 

이 두 함수를 쓸려던 찰나에, 개인적으로 고민되었던 점이 있다.

'그럼 영문말고 다른 문자가 들어오는 경우를 위해 예외처리를 해줘야 하나?'

맨 처음에 코드를 짤 때는 예외처리를 해줬었는데, 시험삼아 그 코드를 지워보았더니

똑같이 정답이 나와서 검색을 해봤다! 

 

그 결과, tolower과 toupper는, 자신들이 변경해주어야 하는 문자(tolower: 대문자/toupper:소문자)이외의

다른 문자는 모두 그대로 반환한다고 한다! 

즉, 별도의 처리없이 살펴보는 문자에 저 두 함수중 하나를 통일되게 사용하여 비교해주면 된다.

 

※getline(istream& is, string str);
  getline(istream& is, string str, char dlim);
: 원하는 구분자(delimiter)를 만날 때 까지 모든 문자열을 입력 받아 하나의 string 객체에 저장

 

cin>> 을 이용하여 문자를 입력하게 되면, 공백을 입력받을 수 없다.

>>연산자가 공백문자에서 입력을 종료하기 때문인데, 이를 해결하기 위해 getline() 함수를 사용한다.

 

getline함수는 getline(cin, string) 과 같은 형태로, 구분자없이 사용도 가능하다.

하지만 이때 주의할 점이 있다.

 

int n;
string s;
cin>>n;
getline(cin,s);

위의 코드를 실행하면 n을 입력받은 후, s에 문자열을 입력받지 않고 넘어가게 된다.

버퍼에 정수값 n을 입력한 뒤 누른 엔터('\n')가 그대로 남아있어서 getline()에 들어갔기 때문이다.

이를 해결하기 위해서는 cin.ignore() 함수를 사용해야 한다.

n을 입력받은 뒤 cin.ignore()을 적게 되면 입력 버퍼의 모든 내용을 제거해주기 때문에

getline()이 정상적으로 작동한다.

cin.ignore()에 대한 자세한 설명은 검색창에 검색해보길 바란다.

문제를 풀면서 내가 참고했던 사이트도 참고자료에 링크를 걸어둘테니 참고해도 좋을 것 같다!

 

2) 최종 소스코드
#include <bits/stdc++.h>
using namespace std;
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n;
	cin >> n;
	cin.ignore(); //입력버퍼 내용 제거
	for(int k=0;k<n;k++){
		string s;
		getline(cin, s);
		bool isP = true; //yes, no 판단해줄 bool 변수
		int j = s.size() - 1; //맨뒤 문자의 인덱스
		for (int i = 0; i <= j; i++) {
				s[i] = toupper(s[i]); //비교해줄 문자를 대문자로 통일
				s[j] = toupper(s[j]); //비교해줄 문자를 대문자로 통일
			if (s[i] != s[j]) {
				isP = false;
				break;
			}
			j--; 
		}
		if (isP) cout << "Yes" << '\n';
		else cout << "No" << '\n';
	}
}
3) 참고자료

kyu9341.github.io/C-C/2020/01/17/C++getline()/

hyeonstorage.tistory.com/306

blockdmask.tistory.com/452

728x90