题目描述:
分析:
将编码理解为二进制,用(len, value)这个二元组来表示一个编码,其中len是该编码的长度,value是该编码对应的十进制值,我们使用code这个二维数组来表示,注意编码长度从1开始,最长是7。
代码块:
//注释代码行是调试用,输出中间结果,包括printcodes()函数。
#include <cstdio>
#include <cstring> // 使用 memset
using namespace std;
int readchar ()
{
for(;;) {
int ch = getchar(); //从输入中读取一个字符
if(ch != '\n' && ch != '\r') return ch; // 一直读到下一个非换行符为止
}
}
int readint (int c)
{
int v = 0;
while(c--) v = v * 2 + readchar() - '0'; // 读取c个字符,将其从2进制转换到十进制
return v;
}
int code[8][1<<8];
//编码储存,一维表示该编码长度(二进制位数),二维表示编码对应的十进制值,最大可表示十进制2^8
//code[0]是不用的 , 编码长度从1开始,最多7位
int readcodes()
{
memset(code, 0, sizeof(code)); // 清空数组
code[1][0] = readchar(); //直接调到下一行开始读取。如果输入已经结束,读到EOF
for(int len = 2; len <= 7; len++) { // 从长度为2的编码开始读取,上述已经读取长度为1的编码
for(int i = 0; i < (1<<len) - 1; i++) {
//对于给定长度的编码(二进制位数),最大值为(2^len)-1,不存在1的情况
int ch = getchar();
if(ch == EOF) return 0; // 输入结束
if(ch == '\n' || ch == '\r') return 1; // 一行编码头读取完毕
code[len][i] = ch; // 储存该编码头字符,逐字符读取
}
}
return 1;
}
// 本函数不是必须的,调试用
void printcodes()
{
for(int len = 1; len <= 7; len++)
for(int i = 0; i < (1<<len)-1; i++) {
if(code[len][i] == 0) break; // 所有编码字符读取完毕
printf("code[%d][%d] = %c\n", len, i, code[len][i]);
}
}
int main(void)
{
while(readcodes()) { //无法读取更多编码头时退出
//printcodes();
for(;;) {
int len = readint(3); // 读取编码文本的每小节长度
if(len == 0) break; // 000编码结束
//printf("len=%d\n", len);
for(;;) {
int v = readint(len); //每次读取小节给定的长度
//printf("v=%d", v);
if(v == (1<<len)-1) break; // 小节结束,每位都是1
putchar(code[len][v]); // 输出解码后的字符
}
}
putchar('\n');
}
return 0;
}