PTA-莫尔斯码(字符串,模拟)
原题
大家有木有看过带谍战剧?里面多数都有发电报的情节吧,有木有感觉滴滴答答地发报特别酷?
发报的那个东西,学名叫做“电键”,如图:
电键按下去之后,电路接通,就会发出声音,长短不同的声音组合,就形成了不同的编码,可以表示不同的信息~
汉字个数太多,所以汉字的编码是很复杂的。但是英文字母比较少,编码就容易多了
我们今天来研究一种国际通用的电报编码——莫尔斯码。
我们用“滴(Di~)”来模拟电键短按发出的声音,用一个点(dot)表示: .
用“答(Da~)”来模拟电键长按发出的声音,用一个短划(dash)表示: -
英文字母和数字的莫尔斯码是:
A .-
B -…
C -.-.
D -…
E .
F …-.
G --.
H …
I …
J .—
K -.-
L .-…
M –
N -.
O —
P .–.
Q --.-
R .-.
S …
T -
U …-
V …-
W .–
X -…-
Y -.–
Z --…
0 -----
1 .----
2 …—
3 …–
4 …-
5 …
6 -…
7 --…
8 —…
9 ----.
例如求救信号 SOS 的莫尔斯码就是: … — … (每个字母的编码中间空一格)
现在请将输入的编码转成文本、将输入的文本转成编码。
输入格式:
第一行为一个正整数N,
接下来N行,每行为不超过200个字符的文本或者编码。
我们把连续的一串字母或数字的组合称之为一个“单词”,输入的文本格式是:每个单词之间空一格,文本的首末两端没有空格,例如CQ CQ,文本仅有大写字母、数字、空格组成。
输入的编码的格式是:每个单词内的字母编码或数字编码之间空一格,每个单词之间用|分隔,例如 -.-. --.-|-.-. --.- (文本 CQ CQ的编码)
输出输入格式:
对每一行输入的文本或编码,采用相对应的格式,在一行中对应给出其编码或文本。
输入样例:
2
-.-. --.-|-.-. --.-|-.-. --.-|-… .|-… -… … … .-… .-|-… -… … … .-… .-|-.-
CQ CQ CQ DE BD5HLA BD5HLA K
输出样例:
CQ CQ CQ DE BD5HLA BD5HLA K
-.-. --.-|-.-. --.-|-.-. --.-|-… .|-… -… … … .-… .-|-… -… … … .-… .-|-.-
题意
给定字符与莫尔斯码的对应关系,要求将文本转换成编码,或将编码转换成文本。
和去年天梯赛的AI代码一样,忠实题意模拟即可
关系存储
这里可以用一个一维字符数组存单个字符,然后二维数组存莫尔斯码,但这在查找比较的时候较复杂,速度也慢。这里我用map存储,不过存入时代码比较多。
map<char , string>m1;
map<string , string>m2;
freopen("output.txt" , "r" , stdin);
string s1 , s2;
while(cin>>s1>>s2)
{
cout<<"m1["<<"'"<<s1<<"']"<<" = "<<"\""<<s2<<"\";"<<endl;
cout<<"m2["<<"\""<<s2<<"\"]"<<" = "<<"\""<<s1<<"\";"<<endl;
}
这里直接运行上面这段程序,再将上面的关系复制进来,最后将输出的内容拷贝到编译器即可。
判断文本或者是编码
这里用“|”去区分文本或者是编码恐怕有失偏颇,万一编码只有一组岂不是同样没有“|”
所以采用“.”和“-”来进行区分。注意到有的编码只有“.”有的编码只有“-”,所以如果是文本的话,应该同时不含有“.”和“-”。
bool flag = false;
if(str.find(".") == string :: npos && str.find("-") == string :: npos)
flag = true;
这里可以用string 的find函数,string::npos就是空的意思。通过flag的值决定进行何种转换
文本转编码
因为刚刚用了map进行存储,所以只需要遍历输入进来的字符串即可,碰到字符直接输出对应的编码,碰到空格就输出"|",这里尤其注意什么时候输出空格。得是下一个字符不是字母才能输出空格,并且得保证判断的时候下标不越界,最后输出换行。
for(int i = 0 ; i < str.length() ; i++)
{
if(str[i] != ' ')
{
cout<<m1[str[i]];
if(i + 1 < str.length() && str[i + 1] != ' ')
cout<<" ";
}
else
cout<<"|";
}
cout<<endl;
编码转文本
这里就比较复杂了,因为题目输入的是一整串文本,而我们需要的是其中一段一段才更好处理。这里可以用c++的sstream或者是c的ssprint,用于字符串的二次读入储存。我们观察到不同组的编码通过“|”分隔,但实际上我们处理的时候并没有很大价值,如果是换成空格分割会好些,但换成空格又和原本的空格产生歧义,所以这里考虑塞进一个不相干的字符进去,用于区别是否是同种字符,这里我采用“a”。
while(str.find("|") != string :: npos)
str.replace(str.find("|") , 1 , " a ");
stringstream ss(str);
int k = 0;
while(ss >> str)
s[k++] = str;
这里把“|”替换成“ a ”,再把得到的字符串输入进一个字符串数组里。
举个例子,比如:-.-. --.-|-.-. --.-|-.-. --.-|
处理后
- s[0] = “-.-”.
- s[1] = “–.-”
- s[2] = “a”
- s[3] = “-.-.”
- s[4] = “–.-”
- s[5] = “a”
- s[6] = “-.-.”
- s[7] = “–.-”
- s[8] = “a”
这样我们处理起来就很方便了,不是a的话就直接输出对应的字符,是a就输出空格
for(int i = 0 ; i < k ; i++)
{
if(s[i] != "a")
cout<<m2[s[i]];
else
cout<<" ";
}
cout<<endl;
代码
//7-13 莫尔斯码(Morse Code) (15分)
#include<map>
#include<cstdio>
#include<sstream>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
map<char , string>m1;
map<string , string>m2;
int main()
{
// freopen("output.txt" , "r" , stdin);
// string s1 , s2;
// while(cin>>s1>>s2)
// {
// cout<<"m1["<<"'"<<s1<<"']"<<" = "<<"\""<<s2<<"\";"<<endl;
// cout<<"m2["<<"\""<<s2<<"\"]"<<" = "<<"\""<<s1<<"\";"<<endl;
// }
m1['A'] = ".-";
m2[".-"] = "A";
m1['B'] = "-...";
m2["-..."] = "B";
m1['C'] = "-.-.";
m2["-.-."] = "C";
m1['D'] = "-..";
m2["-.."] = "D";
m1['E'] = ".";
m2["."] = "E";
m1['F'] = "..-.";
m2["..-."] = "F";
m1['G'] = "--.";
m2["--."] = "G";
m1['H'] = "....";
m2["...."] = "H";
m1['I'] = "..";
m2[".."] = "I";
m1['J'] = ".---";
m2[".---"] = "J";
m1['K'] = "-.-";
m2["-.-"] = "K";
m1['L'] = ".-..";
m2[".-.."] = "L";
m1['M'] = "--";
m2["--"] = "M";
m1['N'] = "-.";
m2["-."] = "N";
m1['O'] = "---";
m2["---"] = "O";
m1['P'] = ".--.";
m2[".--."] = "P";
m1['Q'] = "--.-";
m2["--.-"] = "Q";
m1['R'] = ".-.";
m2[".-."] = "R";
m1['S'] = "...";
m2["..."] = "S";
m1['T'] = "-";
m2["-"] = "T";
m1['U'] = "..-";
m2["..-"] = "U";
m1['V'] = "...-";
m2["...-"] = "V";
m1['W'] = ".--";
m2[".--"] = "W";
m1['X'] = "-..-";
m2["-..-"] = "X";
m1['Y'] = "-.--";
m2["-.--"] = "Y";
m1['Z'] = "--..";
m2["--.."] = "Z";
m1['0'] = "-----";
m2["-----"] = "0";
m1['1'] = ".----";
m2[".----"] = "1";
m1['2'] = "..---";
m2["..---"] = "2";
m1['3'] = "...--";
m2["...--"] = "3";
m1['4'] = "....-";
m2["....-"] = "4";
m1['5'] = ".....";
m2["....."] = "5";
m1['6'] = "-....";
m2["-...."] = "6";
m1['7'] = "--...";
m2["--..."] = "7";
m1['8'] = "---..";
m2["---.."] = "8";
m1['9'] = "----.";
m2["----."] = "9";
int n;
string str;
string s[210];
cin>>n;
getchar();
while(n--)
{
getline(cin , str);
// cout<<s1<<endl;
bool flag = false;
if(str.find(".") == string :: npos && str.find("-") == string :: npos)
flag = true;
if(flag)
{
for(int i = 0 ; i < str.length() ; i++)
{
if(str[i] != ' ')
{
cout<<m1[str[i]];
if(i + 1 < str.length() && str[i + 1] != ' ')
cout<<" ";
}
else
cout<<"|";
}
cout<<endl;
}
else
{
while(str.find("|") != string :: npos)
str.replace(str.find("|") , 1 , " a ");
// cout<<str<<endl;
stringstream ss(str);
int k = 0;
while(ss >> str)
s[k++] = str;
for(int i = 0 ; i < k ; i++)
{
if(s[i] != "a")
cout<<m2[s[i]];
else
cout<<" ";
}
cout<<endl;
}
}
return 0;
}