传送门:题目链接
思路:做一个循环,每个循环都包含一下三步:
第一步,就是用自己写的my_getline获取文件的一行header(为什么自己写?因为在联系C不想用C++而且gets不安全再者输入有空格等),其中要注意:获取一行字符串结束时要在对应地址末尾加上'\0'作为结束符;而结束获取的标志有EOF,'\n','\r'三者。
第二步,处理header和二进制数(msg)的关系。这里注意到利用二进制及其题目本身的特点,想到用长度len去重。所以做一个table[len][max_value]表达(len,value)并存放对应的header中的字符。
第三步,读取msg。由于输入的任意性(行随意),可以想象必须边读边操作边输出得到答案。所以根据步骤,我们做一个函数readint(num)用来读取msg中前num个数并返回其十进制值。这样就可以做一个循环,不断用readint(3)先获取接下来的编码长度(存为len),然后再不断readint(len)直到其值是2^len - 1时跳出……当readint(3)得到0时意味着此次循环结束。但是注意,末尾可能有换行符!所以用getchar()获取,得到的要么是EOF(最外围的循环结束),要么是换行符。
#include<stdio.h>
//#include<time.h>
//#include<string.h>
char header[6666];
char table[8][(1<<7)];//(len, value) -> char_in_header
int my_getline(char *header){
//get the line of the stdin, terminated by '\n' or '\r' or EOF; return the length of the string
int temp;
int i = 0;
while(EOF != (temp = getchar())){
if(temp !='\n' && temp != '\r'){
*(header + i) = (char)temp;
i++;
}
else break;
}
//attention: put '\0' at the end
*(header + i) = '\0';
if(temp == EOF) return EOF;
else return i;
}
int readbit(int num){
//read num bits(0 or 1) from stdin, return the decimal value
char temp;
int ans = 0;
int times = 0;
while(times < num && (temp = getchar())){
if(temp != '\r' && temp != '\n'){
times++;
ans += (temp - '0') * (1<<(num - times));
}
}
return ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(EOF != my_getline(header)){//input the header
//cope with the header map to the bit codes
int ptr = 0;
for(int i = 1; header[ptr]; i++){
int range = (1<<i) - 1;
for(int j = 0; j < range && header[ptr]; j++){
table[i][j] = header[ptr++];
}
}
//input the message
int len;
while((len = readbit(3))){
int value;
while(1){
value = readbit(len);
if(value == (1 << len) - 1) break;
putchar(table[len][value]);
}
}
putchar('\n');
if((len = getchar()) && len == EOF) break;//attention: read '\n' at the end!!! ,or EOF
}
//printf("Total time: %.4f s.", (double)clock()/CLOCKS_PER_SEC);
return 0;
}