나무 숲
회문 (Palindrome, 回文, 팰린드롬) 본문
회문
Palindrome, 回文
회문(回文) 또는 팰린드롬(palindrome)은 앞에서 읽으나 거꾸로 읽으나 같은 문장이나 낱말을 뜻합니다. 보통 낱말 사이에 있는 띄어쓰기나 문장 부호는 무시한다..고 하지만 알고리즘 문제를 풀 때에는 고려하는 경우도 있으므로 문제 조건을 잘 읽어보는 것이 좋습니다.
한국어에서의 예
- 기러기
- 다 간다 이 일요일 일요일이 다 간다
영어에서의 예
- race car
- A man, a plan, a caret, a ban, a myriad, a sum, a lac, a liar, a hoop, a pint, a catalpa, a gas, an oil, a bird, a yell, a vat, a caw, a pax, a wag, a tax, a nay, a ram, a cap, a yam, a gay, a tsar, a wall, a car, a luger, a ward, a bin, a woman, a vassal, a wolf, a tuna, a nit, a pall, a fret, a watt, a bay, a daub, a tan, a cab, a datum, a gall, a hat, a fag, a zap, a say, a jaw, a lay, a wet, a gallop, a tug, a trot, a trap, a tram, a torr, a caper, a top, a tonk, a toll, a ball, a fair, a sax, a minim, a tenor, a bass, a passer, a capital, a rut, an amen, a ted, a cabal, a tang, a sun, an ass, a maw, a sag, a jam, a dam, a sub, a salt, an axon, a sail, an ad, a wadi, a radian, a room, a rood, a rip, a tad, a pariah, a revel, a reel, a reed, a pool, a plug, a pin, a peek, a parabola, a dog, a pat, a cud, a nu, a fan, a pal, a rum, a nod, an eta, a lag, an eel, a batik, a mug, a mot, a nap, a maxim, a mood, a leek, a grub, a gob, a gel, a drab, a citadel, a total, a cedar, a tap, a gag, a rat, a manor, a bar, a gal, a cola, a pap, a yaw, a tab, a raj, a gab, a nag, a pagan, a bag, a jar, a bat, a way, a papa, a local, a gar, a baron, a mat, a rag, a gap, a tar, a decal, a tot, a led, a tic, a bard, a leg, a bog, a burg, a keel, a doom, a mix, a map, an atom, a gum, a kit, a baleen, a gala, a ten, a don, a mural, a pan, a faun, a ducat, a pagoda, a lob, a rap, a keep, a nip, a gulp, a loop, a deer, a leer, a lever, a hair, a pad, a tapir, a door, a moor, an aid, a raid, a wad, an alias, an ox, an atlas, a bus, a madam, a jag, a saw, a mass, an anus, a gnat, a lab, a cadet, an em, a natural, a tip, a caress, a pass, a baronet, a minimax, a sari, a fall, a ballot, a knot, a pot, a rep, a carrot, a mart, a part, a tort, a gut, a poll, a gateway, a law, a jay, a sap, a zag, a fat, a hall, a gamut, a dab, a can, a tabu, a day, a batt, a waterfall, a patina, a nut, a flow, a lass, a van, a mow, a nib, a draw, a regular, a call, a war, a stay, a gam, a yap, a cam, a ray, an ax, a tag, a wax, a paw, a cat, a valley, a drib, a lion, a saga, a plat, a catnip, a pooh, a rail, a calamus, a dairyman, a bater, a canal - Panama! (파나마 운하 건설 당시 사용되었던 회문)
그렇다면 이러한 회문을 판별하는 알고리즘은 어떻게 구현할 수 있을까요?
그냥 생각만 해봐도 매우 쉽..네요 ㅎㅎ;;
아래의 코드들은 다 주관적으로 짠 것이라.... 그저 저의.. 방법... 비효율적일 수 있는 제 방법.. 일 뿐이니.. 참고만 해주시길 바래요..ㅎㅎ
가장 간단하게는..
위와 같은 회문을 검사한다고 할 때, 그냥 앞과 뒤를 하나씩 비교해주면 될 듯 합니다.
그러니 반까지만 확인을 하면 되겠죠?
조건
- 대소문자 구분한다. (r과 R은 다르다)
- 띄어쓰기 구분한다. ('rr r'은 회문이 아니다)
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
getline(cin, s);
int len = s.length();
int halflen = len/2;
for (int i = 0; i < halflen; i++){
if (s.at(i) != s.at(len - 1 - i)){
cout << "NOT Palindrome" << endl;
return 0;
}
}
cout << "Palindrome"<<endl;
return 0;
}
두 번째로, 대소문자를 구분하지 않는 방법입니다.
저같은 경우는 걍 조건문에 때려넣었습니다.
조건
- 대소문자 구분하지 않는다. (r과 R은 같다)
- 띄어쓰기 구분한다. ('rr r'은 회문이 아니다)
#include<iostream>
#include<string>
using namespace std;
int main(){
string s; int i;
getline(cin, s);
int len = s.length();
int halflen = len / 2;
for (i = 0; i<halflen; i++){
if ((((s.at(i) >= 'A') && (s.at(i) <= 'Z')) || ((s.at(i) >= 'a') && (s.at(i) <= 'z'))) && (((s.at(len - i - 1) >= 'A') && (s.at(len - i - 1) <= 'Z')) || ((s.at(len - i - 1) >= 'a') && (s.at(len - i - 1) <= 'z')))){ //char일 때
if ((s.at(i) - s.at(len - i - 1)) == 32 || (s.at(len - i - 1) - s.at(i)) == 32 || (s.at(len - i - 1) == s.at(i))){
}
else{
cout << "NOT Palindrome" << endl;
break;
}
}
else if (s.at(len - i - 1) != s.at(i)){
cout << "NOT Palindrome" << endl;
break;
}
}
if (i == halflen){
cout << "Palindrome" << endl;
}
return 0;
}
세 번째, 띄어쓰기를 무시하는 알고리즘입니다.
이 경우에는.. 반만 탐색할 수 없습니다.. 그래서 두 개의 기준을 세웠습니다.
그리고 이 두 화살표가,
똑같은 위치를 가리키거나(띄어쓰기 제외한 글자 수가 홀수일 때), 바로 옆에 있을 때(띄어쓰기 제외한 글자 수가 짝수일 때) 모든 글자를 확인한 것인데요, 더 간단하게 생각해보면 초록 화살표가 연두 화살표와 같거나, 더 왼쪽에 있을 때..! 다 확인하고도 남았다고 할 수 있겠군요.
이것도 그냥 조건 때려박아!!
조건
- 대소문자 구분하지 않는다. (r과 R은 같다)
- 띄어쓰기 구분하지 않는다. ('rr r'은 회문이다)
#include<iostream>
#include<string>
using namespace std;
int main(){
string s; int i;
getline(cin, s);
int len = s.length();
int halflen = len / 2;
int left = 0; int right = len - 1;
while(true){
while (s.at(left) == ' ') left++;
while (s.at(right) == ' ') right--;
if (right>=left) break;
if ((((s.at(left) >= 'A') && (s.at(left) <= 'Z')) || ((s.at(left) >= 'a') && (s.at(left) <= 'z'))) && (((s.at(right) >= 'A') && (s.at(right) <= 'Z')) || ((s.at(right) >= 'a') && (s.at(right) <= 'z')))){
if ((s.at(left) - s.at(right)) == 32 || (s.at(right) - s.at(left)) == 32 || (s.at(right) == s.at(left))){
}
else{
cout << "NOT Palindrome" << endl;
return 0;
}
}
else if (s.at(right) != s.at(left)){
cout << "NOT Palindrome" << endl;
return 0;
}
}
cout << "Palindrome" << endl;
return 0;
}
(이 코드를 짜고 나니 두 번째 내용을 더 깔끔하게 수정해서 이것도 고치고 싶었지만 귀찮아서.. ㅎㅎ..)
-
https://ko.wikipedia.org/wiki/%ED%9A%8C%EB%AC%B8
'Career > 알고리즘 · 자료구조' 카테고리의 다른 글
프로그래머스 / 멀쩡한 사각형 (0) | 2020.08.21 |
---|---|
이진 트리 (Binary Tree) - 구현 (0) | 2017.07.06 |
수학/ 중국인의 나머지정리 Chinese remainder theorem (0) | 2017.05.06 |
[DP] 파도반 수열 Padovan sequence (0) | 2017.04.06 |
피보나치 수열 Fibonacci Numbers / Fibonacci Sequence (0) | 2017.04.03 |