// 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]