uva213 Message Decoding

题意  编写一个解码程序   对数字串进行解码

输入分为两部分,一部分是编码头,如TNM AEIOU,第二部分是经过编码之后的信息,是0和1的字符串,编码之后的0和1字符串输入可能会多行,最后结尾为000字符串。编码映射规则如下,编码头和0和1字符串对应,对应的0和1字符串为0,00,01,10,000,001,011,100,101,110,0000,0001,...,1101,1110,00000,.......,首先是长度为1的串,然后是长度为2的串,然后是长度为3的串,以此类推,相同长度的串二进制串不能出现都为1的情况,如1,11,111等,相同长度的串的后一个串等于前一个串加1,所以长度为1,2,3的串的数量为1,3,7,即(1<<n)-1,n为字符串长度。映射规则如T对应0,N对应00,M对应01,“ ”对应10,A对应000,如此顺序对应。

输入的第二部分是编码之后的信息,你需要做的就是根据上面的映射关系对二进制信息进行解码,二进制信息编码规则如下,分为很多部分,每个部分首先是三个长度的01编码,如编码头为TAM AEIOU的编码信息0010101100011 1010001001110110011 11000,首先是三个长度为1的串001,表示后面接长度为1的串,0,映射T,1表示长度为1的串结束,再输入三个字符,011,长度为三的串开始000映射A,111表示长度为3的串结束,再输入三个编码,以此类推,直到最后结束字符串000,通过解码得到字符串序列为,0,000,00,10,01,001;根据前面的编码映射规则,解码得到TAN ME。

此题是算法竞赛入门经典第二版中的例题   第83页   里面有详细的讲解;

解题思路,因为本题使用二进制字符串编码问题,考虑用二进制来生成一一映射关系,使用二维数组来对应相关的编码头和二进制编码,code[8][1<<8],代码实现如下:

 1 int code[8][1<<8];
 2 int readcodes()
 3 {
 4     memset(code,0,sizeof(code));
 5     code[1][0]=readchar();
 6     for(int len = 2;len<=7;len++){
 7         for(int i=0;i<(1<<len)-1;i++){
 8             int ch = getchar();
 9             if(ch == EOF)return 0;
10             if(ch == '
' || ch == '
')return 1;
11             code[len][i]=ch;
12         }
13     }
14     return 1;
15 }

对输入的字符串进行解码得到十进制数。

1 int readint(int c)
2 {
3     int v = 0;
4     while(c--)v=v*2+readchar()-'0';
5     return v;
6 }

跳过01字符串中的换行符:

1 int readchar()
2 {
3     while(1){
4         int ch = getchar();
5         if(ch != '
'&&ch!='
')return ch;
6     }
7 }

主函数如下:

 1 #include <iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 
 6 int main() {
 7     while(readcodes()){
 8         while(1){
 9             int len = readint(3);
10             if(len==0)break;
11             while(1){
12                 int v = readint(len);
13                 if(v == (1<<len)-1)break;
14                 putchar(code[len][v]);
15             }
16         }
17         putchar('
');
18     }
19     return 0;
20 }
原文地址:https://www.cnblogs.com/ArvinShaffer/p/7619901.html