이 문제에서는 하나의 문장이 주어지며, 우리의 목표는 그 문장 안에서 '재미있는 단어(funny word)'에 해당하는 모든 단어를 찾아 출력하는 것입니다.
재미있는 단어란 무엇일까?
재미있는 단어는 다음 조건을 만족하는 단어입니다. 문자열의 인접한 두 문자 사이의 절대 차이가, 해당 문자열을 뒤집은 문자열(reverse string)의 인접한 두 문자 사이의 절대 차이와 서로 같아야 합니다.
|string[0] - string[1]| = |revstring[0] - revstring[1]|
예시로 이해하기
입력: string = 'ABRS' 출력: Yes 설명: 뒤집은 문자열 = SRBA |A-B| = 1 = |S-R| |B-R| = 16 = |R-B| |B-A| = 1 = |R-S|
위 예시에서 원본 문자열 'ABRS'와 뒤집은 문자열 'SRBA'의 인접 문자 간 절대 차이가 모든 위치에서 일치하므로, 'ABRS'는 재미있는 단어에 해당합니다.
문제 해결 접근 방법
이 문제는 크게 두 단계로 나누어 해결할 수 있습니다.
1. 주어진 문장을 공백을 기준으로 나누어 각 단어를 하나씩 추출합니다.
2. 추출한 단어가 재미있는 문자열인지 검사하고, 조건을 만족하는 경우에만 출력합니다.
재미있는 문자열 검사 방법
검사를 진행할 때는 문자열을 양쪽 끝, 즉 앞부분과 뒷부분에서 동시에 순회하면서 인접 문자 간의 절대 차이를 비교합니다. 순회 도중 어느 지점에서든 차이가 일치하지 않으면 false를 반환하여 해당 단어가 재미있는 단어가 아님을 판별합니다. 참고로 한 글자짜리 단어는 비교할 인접 문자 쌍이 존재하지 않으므로 항상 조건을 만족하게 됩니다.
아래 코드는 위에서 설명한 로직을 그대로 구현한 것입니다.
예제 코드
#include <iostream>
#include<string.h>
using namespace std;
bool isFunny(string word){
int i = 1;
int j = word.length() - 2;
for (int i = 0; i < word.length(); i++)
word[i] = tolower(word[i]);
while (i <= j){
if (abs(word[i] -
word[i - 1]) != abs(word[j] -
word[j + 1]))
return false;
i++;
j--;
}
return true;
}
void printFunnyWords(string str){
str +=" ";
string word = "";
for (int i = 0; i < str.length(); i++){
char ch = str[i];
if (ch!=' ')
word += ch;
else{
if (isFunny(word))
cout<<word<<"\t";
word = "";
}
}
}
int main(){
string sentence = "hello, i love malayalam langauge";
cout<<"All funny words of the string '"<<sentence<<"' are :\n";
printFunnyWords(sentence);
return 0;
}실행 결과
All funny words of the string 'hello, i love malayalam langauge' are : i malayalam
실행 결과를 살펴보면, 'hello,'는 쉼표가 포함되어 있고 인접 문자 차이 조건도 만족하지 못하며, 'love'와 'langauge' 역시 뒤집은 문자열과의 절대 차이가 일치하지 않아 제외됩니다. 반면 한 글자 단어 'i'와 회문(palindrome) 형태를 띠는 'malayalam'만 조건을 통과하여 최종적으로 출력됩니다.