#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
class Morse{
private:
string alphabet[26]; //알파벳의 모스 부호 저장
string digit[10]; //숫자의 모스 부호 저장
string slash, question, comma, period, plus, equal; //특수 문자의 모스 부호 저장
public:
Morse(); //alphabet[], digit[] 배열 및 특수 문자의 모스 부호 초기화
void text2Morse(string text, string& morse); //영문 텍스트를 모스 부호로 변환
bool morse2Text(string morse, string& text); //모스 부호를 영문텍스트로 변환
};
Morse::Morse(){
string Malphabet[26]={ ".-", "-...", "-.-.", "-..", ".","..-.", "--.", "....", "..", ".---",
"-.-", ".-..", "--", "-.", "---",".--.", "--.-", ".-.", "...", "-",
"..-", "...-", ".--", "-..-", "-.--", "--.."};
string Mdigit[10]={"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----." };
slash= "-..-."; question= "..--.."; comma= "--..--";
period= ".-.-.-"; plus= ".-.-."; equal= "-...-"; //모스 특수문자 초기화
int i;
for(i=0;i<26;i++){alphabet[i]=Malphabet[i];} //모스 알파벳 초기화
for(i=0;i<10;i++){digit[i]=Mdigit[i];} //모스 숫자 초기화
}
void Morse::text2Morse(string text, string& morse){
transform(text.begin(),text.end(),text.begin(),tolower); // 입력한 문자열을 전부 소문자로 바꾼다.
for(int i=0;i<text.length();i++){
if(text[i]>=97&&text[i]<=122){morse=morse+alphabet[text[i]-97]+" ";} //해당 인덱스가 알파벳일 경우 해당 모스 부호 삽입
else if(text[i]==' '){morse+=" ";} //해당 인덱스가 공백문자 일경우 공백문자 3개 입력
else if(text[i]>=48&&text[i]<=57){morse=morse+digit[text[i]-48]+" ";} //해당 인덱스가 숫자 일경우 해당 모스 부호 삽입
else if(text[i]=='/'){morse=morse+slash+" ";}
else if(text[i]=='?'){morse=morse+question+" ";}
else if(text[i]==','){morse=morse+comma+" ";}
else if(text[i]=='.'){morse=morse+period+" ";}
else if(text[i]=='+'){morse=morse+plus+" ";}
else if(text[i]=='='){morse=morse+equal+" ";} //해당 인덱스가 특수문자 일경우 해당 모스 부호 삽입
}
}
bool Morse::morse2Text(string morse, string& text){
string regen; //다시 읽을 수 있게 복원한 것을 넣을 스트링
string sub; // 공백 문자 단위로 자름
int i;
int startindex=0; //문자를 찾기 시작할 첫번째 index
int blankindex=-1; //공백문자의 index
int swch=1; //모스부호가 무엇인지 검사하는데 사용할 플래그
while(1){
swch=1; //플래그는 루프 돌때마다 1로 ON
startindex=blankindex+1; //찾기 시작할 인덱스는 공백 인덱스 더하기 1
blankindex=morse.find(" ",blankindex+1); //전에 찾았던 것을 또 찾으면 안되니 더하기 1을해서 공백문자를 찾는다.
sub=morse.substr(startindex,blankindex-startindex); // 공백 문자를 제외한 무언가를 나타내는 모스부호 부분만 자른다.
for(i=0;i<26;i++){
if(alphabet[i]==sub)
{regen+=(char)(97+i);
swch=0;break;} //알파벳일 경우 변환하여 regen에 더하고 플래그 OFF 후 루프 탈출
}
if(swch==1){
for(i=0;i<10;i++){
if(digit[i]==sub)
{regen+=(char)(48+i);
swch=0;break;}
} //숫자일 경우 변환하여 regen에 더하고 플래그 OFF 후 루프 탈출
}
if(swch==1){
if(sub==slash){regen+="/";}
else if(sub==question){regen+="?";}
else if(sub==comma){regen+=",";}
else if(sub==period){regen+=".";}
else if(sub==plus){regen+="+";}
else if(sub==equal){regen+="=";}
} //특수문자일 경우 regen에 더한다.
if(blankindex==morse.length()-1){break;} //여기서 검사하는 이유는 인덱스가 맨 마지막일때 +1,+2,+3 을 검사하면 오류가 나기 때문이다.
if((morse[blankindex+1]==' ')&&(morse[blankindex+2]==' ')&&(morse[blankindex+3]==' ')){
regen+=" "; cout<<regen<<endl; //제대로 이어졌나 확인.
blankindex+=3; //공백문자가 연달아 3개 있으면 실제에서는 공백문자 하나를 뜻한다. 이를 검사하기 위함.
}
}
if(regen==text) return true; //새로 만든 문자열과 원래 문자열이 같으면 true리턴
else return false; //아니면 false 리턴
}
int main(void){
Morse m;
string english;
string morse;
cout<<"아래에 영문 텍스트를 입력하세요. 모스 부호로 바꿉니다."<<endl;
getline(cin,english,'\n'); //개행문자 나올 때까지 문자열 받는다
m.text2Morse(english,morse); //모스부호로 전환
cout<<morse<<endl;
cout<<"모스 부호를 다시 영문 텍스트로 바꿉니다."<<endl;
if(m.morse2Text(morse,english)) //다시 읽을 수 있는 텍스트로 전환
cout<<english<<endl; //만약 같으면 원래 문자열 출력
else
cout<<"오류 발생"<<endl; //다르면 오류발생 출력
return 0;
}