函数与递归-信息解码问题

问题描述:

考虑下面的01串序列:

0,00,01,10,000,001,010,011,100,101,110,0000,0001,....,1101,1110,00000....

首先是长度为1的 串,然后是长度为2的串,以此类推。如果看成二进制,相同长度的后一个串等于前一个串加1.上述序列不存在全为1的串。

我们的任务是编写一个解码程序。

首先输入一个编码头

AB#TAN

则根据上述的规则生成对应的编码

A:0 B:00 #: 01 T: 10 A: 000 N: 001 

这里标红的地方需要注意,此时的编码  0 对应A 001 也对应A

在编码结束后,输入要解码的 编码文本

0100100101101100000111100101

解码过程:

010表示编码长度为2  01  00 10 11代表小节结束 011表示编码长度为3  000 001 111代表小节结束  001 表示编码长度为1 0 1结束

                                   #    B   T                                                                 A     N                                                                    A

先上代码跟结果,再分析

代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

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';
    return v;
}

int code[8][1<<8];
int readcodes(){
    memset(code, 0, sizeof(code));
    code[1][0] = readchar();
    int len, i;
    for(len = 2; len <= 7; len++){
        for(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;
}

void printcodes(){
    int len, i;
    for(len = 1; len <= 7; len++)
        for(i = 0; i < (1<<len)-1; i++){
            if(code[len][i] == 0)return;
            printf("code[%d][%d] = %c\n", len, i, code[len][i]);
        }
}

int main()
{
    while(readcodes()){
    printcodes();//调试使用,可以注释掉
        for(;;){
            int len = readint(3);
            if(len == 0) break;
            for(;;){
                int v = readint(len);
                if(v == (1 << len)-1)break;
                putchar(code[len][v]);
            }
        }
        putchar('\n');
    }
    return 0;
}

结果:

分析:
我们把编码看成二进制数,这样我们用(len,value)这个二元组来表示一个编码,其中len是编码长度,value是编码对应的十进制值。用codes[len][value]保存这个编码所对应的字符。由于每次读取编码头时把codes数组清空了,所以只要遇到字符为0的情况,就表示编码头已经结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值