分析:
长度为1的串,可以放1个编码
长度为2的串,可以放3个编码
长度为3的串,可以放7个编码
.....
长度为n的串,可以放 n^2 -1 个编码
思路:
1. 用 1<<n 表示 2^n;
2.
读取编码头:
用codes[][]存储编码头;
Len表示 长度为Len的串
value表示 长度为Len的串的第value个值
例如:长度为 3 的第 2 个编码
先一次输入多个字符,然后用循环调用getchar函数,使其到缓冲区逐一读取字符,并按规律放到codes[Len][value]里面,直到读取到换行符或EOF结束.
3.
读取二进制密文:
①先用循环读取 3位二进制数的 编码长度 (Len),并从二进制转换成十进制 (Len为0的时候结束循环),
②然后往后每次读取Len位二进制数,并把Len位二进制数值转换成十进制value,
③然后用 Len 和 value 到 codes[][] 里面找到对应的编码
④直到读取到 Len位二进制数全为1的时候,即 value = (1<<Len) -1 的时候 结束,跳到 ①
多行读取思路:
用for(;;)循环调用getchar 读取字符,当遇到\n \t的时候,就跳过,然后往下读取,当读取到非换行符的时候,就跳出循环。
#include<iostream>
using namespace std;
char codes[10][1 << 10 - 1]; // 即 codes[10][ 2^10 -1]
//读取字符
int readchar() {
for (;;) {
int ch = getchar();
if (ch != '\n'&&ch != '\t') //如果出现回车或换行 ,则跳过回车或换行,往后读取一个字符 (实现多行读取)
return ch;
}
}
//读取密文
int readint(int n) {
int i, v = 0;
for (i = n - 1; i >= 0; i--)
v += (readchar() - '0') * (1 << i); //转换成10进制
return v;
}
//读取编码头
int readcode() {
int len, i;
memset(codes, 0, sizeof(codes));
for (len = 1; len <= 9; len++) {
for (i = 0; i < (1 << len) - 1; i++) {
char ch = getchar();
if (ch == EOF)return 0;
if (ch == '\n' || ch == '\t')return 1; //遇到换行则读取结束
codes[len][i] = ch;
}
}
return 1; // 超过数codes组范围则读取结束
}
int main() {
int Len;
int p = 0, k = 0;
int value = 0;
readcode();
while (1) {
Len = 0; //编码长度
Len = readint(3);
if (Len == 0)break;
while (1) {
value = 0;
value = readint(Len); //读取Len位二进制数值,并转换成十进制
if (value == (1 << Len) - 1)break; //如果编码全为1,则跳出循环
putchar(codes[Len][value]);
}
putchar('\n');
}
return 0;
}