算法竞赛入门经典4-4信息解码
程序员文章站
2024-03-18 22:07:28
...
题目
下面这个字符串:
0,00,01,10,000,001,010,011…….
首先是长度为1的串,然后是长度为2的串,以此类推。不存在全为1的串。
你的任务是编写一个程序。首先输入一个代码头(例如AB#TANCnrtXz),则上述序列的每个串依次对应编码头的每个字符。例如,0对应A,00对应B,01对应#…,0000对应z。
接下来是编码文本(可能由多行组成,你应当把他们拼成一个长长的01串)。
编码文本由多个小节组成,每个小节的前3个数字代表小节中每个编码的长度,用二进制表示,然后是个字符的编码,以全1结束。编码文本以000结束。
$#**
0100000101101100011100101000
分析理解
1.考察简单2进制转换10进制
2.用数组保存01字串
3.注重审题找到构建数组的关键 也就是如何直接调用编码头
代码(书上的原代码加上我的注释)
#include<stdio.h>
#include<string.h>
int code[8][1<<8];
int readchar(){
for(;;){
int ch = getchar();//getchar输入的保存的就是字符 char型储存字符时是保存的ASCII值 本质上是一种无符号整型值 所以用int也可以储存字符
if(ch!='\n'&&ch!='\r') return ch;//遇到非换行符 返回ch的值
}
}
int readint(int c){//输入c位字符 并转换成十进制数
int v = 0;
while(c--){
v=v*2+readchar() - '0';//读取c位 0或1字符 每读取一个需要把前面的和*2得到十进制数
}
return v;//返回得到的值
}
int readcodes(){
memset(code,0,sizeof(code));//清零避免多组数据时出错
code[1][0]=readchar();//读取第一个字符
for(int len = 2;len <=7; len++){//这两个for循环是为了对应题目 (1,0)0,(2,0)00(2,1) 01(2,2) 10,(3,0)000(3,1) 001(3,2)010 100 101 110,……
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()){//读取编码头 无法读取更多编码头时退出
//printcodes();
for(;;){
int len = readint(3);//获得前三项的十进制值
if(len==0) break;//为0时跳出
//printf("len = %d\n",len);
for(;;){
int v = readint(len);//获得len长的编码十进制数
//printf("v=%d\n",v);
if(v==(1<<len)-1) break; //当全是len长全是1时结束
putchar(code[len][v]);//输出字符
}
}
putchar('\n');
}
return 0;
}