Some message encoding schemes require that an encoded message be sent in two parts. The first part,called the header, contains the characters of the message. The second part contains a pattern that represents the message. You must write a program that can decode messages under such a scheme.The heart of the encoding scheme for your program is a sequence of “key” strings of 0’s and 1’s as
follows:
0;00;01;10;000;001;010;011;100;101;110;0000;0001;…;1011;1110;00000;…
The rst key in the sequence is of length 1, the next 3 are of length 2, the next 7 of length 3, the next 15 of length 4, etc. If two adjacent keys have the same length, the second can be obtained from the rst by adding 1 (base 2). Notice that there are no keys in the sequence that consist only of 1’s. The keys are mapped to the characters in the header in order. That is, the first key (0) is mapped to the rst character in the header, the second key (00) to the second character in the header, the kth key is mapped to the kth character in the header. For example, suppose the header is:
AB#TANCnrtXc
Then 0 is mapped to A, 00 to B, 01 to #, 10 to T, 000 to A, …, 110 to X, and 0000 to c.
The encoded message contains only 0’s and 1’s and possibly carriage returns, which are to be ignored.The message is divided into segments. The rst 3 digits of a segment give the binary representationof the length of the keys in the segment. For example, if the rst 3 digits are 010, then the remainderof the segment consists of keys of length 2 (00, 01, or 10). The end of the segment is a string of 1’swhich is the same length as the length of the keys in the segment. So a segment of keys of length 2 is terminated by 11. The entire encoded message is terminated by 000 (which would signify a segmentin which the keyshave length 0). The message is decoded by translating the keys in the segments one-at-a-time into the header characters to which they have been mapped.
Input
The input le contains several data sets. Each data set consists of a header, which is on a single lineby itself, and a message, which may extend over several lines. The length of the header is limitedonly by the fact that key strings have a maximum length of 7 (111 in binary). If there are multiple copies of a character in a header, then several keys will map to that character. The encoded message contains only 0’s and 1’s,and it is a legitimate encoding according to the described scheme. That is, the message segments begin with the 3-digit length sequence and end with the appropriate sequence of1’s. The keys in any given segment are all of the same length, and they all correspond to characters in the header. The message is terminated by 000.
Carriage returns may appear anywhere within the message part. They are not to be considered as part of the message.
Output
For each data set, your program must write its decoded message on a separate line. There should not be blank lines between messages.
Sample input
TNM AEIOU
0010101100011
1010001001110110011
11000
$#** \
0100000101101100011100101000
Sample output
TAN ME
##*\$
考虑下面的01串序列:
0, 00, 01, 10, 000, 001, 010, 011, 100, 101, 110, 0000, 0001, …, 1101, 1110, 00000, …首先是长度为1的串,然后是长度为2的串,依此类推。如果看成二进制,相同长度的后一个串等于前一个串加1。注意上述序列中不存在全为1的串。
你的任务是编写一个解码程序。首先输入一个编码头(例如AB#TANCnrtXc),则上述序列的每个串依次对应编码头的每个字符。例如,0对应A,00对应B,01对应#,…,110对应X,0000对应c。接下来是编码文本(可能由多行组成,你应当把它们拼成一个长长的01串)。编码文本由多个小节组成,每个小节的前3个数字代表小节中每个编码的长度(用二进制表示,例如010代表长度为2),然后是各个字符的编码,以全1结束(例如,编码长度为2的小节以11结束)。编码文本以编码长度为000的小节结束。
例如,编码头为$#**\,编码文本为0100000101101100011100101000,应这样解码:010(编码长度为2)00(#)00(#)10(*)11(小节结束)011(编码长度为3)000(\)111(小节结束)001(编码长度为1)0($)1(小节结束)000(编码结束)。
#include <stdio.h>
#include <string.h>
// 编码数组
// [len][value]
int code[8][1<<8];
int readChar() {
while(true) {
int ch = getchar();
// 读到非换行符为止
if(ch != '\n' && ch != '\r') {
return ch;
}
}
}
int readInt(int c) {
int v = 0;
// 获取十进制整数
while(c--) {
v = v * 2 + readChar() - '0';
}
return v;
}
int readCodes() {
memset(code, 0, sizeof(code));
// 读取编码头的第一个字符
code[1][0] = readChar();
// 从第二个字符开始循环编码
for(int len = 2; len <= 7; len++) {
for(int i = 0; i < (1 << len) - 1; i++) {
int ch = getchar();
// 文件结束,终止程序
if(ch == EOF) {
return 0;
}
// 读一行
if(ch == '\n' || ch == '\r') {
return 1;
}
code[len][i] = ch;
}
}
return 1;
}
int main() {
while(readCodes()) {
while(true) {
// 读入编码长度
int len = readInt(3);
// 长度为0退出当前编码循环
if(!len) {
break;
}
while(true) {
int v = readInt(len);
// 全为1退出当前小节
if(v == (1 << len) - 1) {
break;
}
putchar(code[len][v]);
}
}
putchar('\n');
}
return 0;
}