例题 4-4 信息解码 (Uva 213)

题目描述:

这里写图片描述

分析:

将编码理解为二进制,用(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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值