// uva 213
// 2017.1.25
#include<stdio.h>
#include<string.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;
} //读入长度为len的二进制的字符串,同时返回对应十进制值
int code[8][1<<8];
int readcodes() {
memset(code, 0, sizeof(code));
code[1][0] = readchar();
for(int len = 2; len <= 7; len++) {
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;
}
//读入编码头,一串字符
void printcodes() {
for(int len = 1; len <= 7; len++)
for(int 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()) { //读入编码头到code数组中。code【编码长度len】【此长度内对应的编码位置value】
//printcodes(); //显示其可以帮助理解!
for(;;) {
int len = readint(3); //读入前3个数,获取长度len
if(len == 0) break;
//printf("len=%d\n", len);
for(;;) {
int v = readint(len); //继续读入长度为len的数,获取该编码的位置value
//printf("v=%d\n", v);
if(v == (1 << len)-1) break;
putchar(code[len][v]); //查code表并且输出
}
}
putchar('\n');
}
return 0;
}
/*
01串序列
二进制:0,00,01,10,000,001,010,011,100,101,110,0000,0001,……
len: 1, 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 , 4 ……
value: 0,0 ,1 ,2 , 0 ,1 ,2 ,3 , 4 ,5 ,6 ,0 ,1 ……
例子 $ # * * \
*/
Input:
$#**\
0100000101101100011100101000
Output:
##*\$
- 注意
题目分析:
①这道题主要考察二进制的东西,有了二进制,我们就不必以字符串的形式保存这一大串编码了,我们只需要把编码理解成二进制,用(len, value)这个二元数组来表示一个编码,其中len表示编码长度,value是编码对应的十进制值
②之后用codes[len][value]保存这个编码所对应的字符,这里需要需要注意我们是这里是单个字符输入的,而且我们编译头是独自一行的。我们这里为什么不考虑,getline因为我们需要每个字符输入和len有直接联系的,所以我们选择单个输入。
③处理比编码文本可以由多行组成这个问题,笔者编写了一个跨行编写读字符的代码
④进制转化问题了,二进制中8位最大的整数是2^8 - 1 用C写是(1 << 8)-1
⑤10进制转化为X进制
while(n != 0)
{
num[i] = n % x;
i++;
n = n/x;
}
X进制转为10进制
for(int i = 0;i < length; i++)
{
ans = ans * X + num[i];
}
- 过程
- 读入编码头到 表code[len][value]中
- 读入三个二进制数获取长度
- 向后继续读入,获取对应长度的对应第几位置
- 查表code[len][value]