這是書上一條例題昂验,那個覺得有意思就也寫一下心得
題目
UVa213
講解與心得
首先從輸入入手
輸入每次輸入有三部分液样,分別是:編碼頭code(一串字符串且含空格)祟剔,編碼文件小節(jié)長度len(只含有1挚歧、0)于宙,以及編碼文件內(nèi)容(只含有1浮驳、0)。所以一共需要三個循環(huán)捞魁,每個循環(huán)對應一部分至会。
第一部分
讀入code[ len ][value],用一個函數(shù)readcode裝起來谱俭,放在 while 循環(huán)的條件里面奉件。當讀到EOF的時候返回0結(jié)束循環(huán)。函數(shù)內(nèi)部第一個細節(jié)是第一個字符用 readchar (自定義函數(shù))讀入昆著,防止讀到回車鍵县貌。剩下的用兩層循環(huán)getchar讀入即可。
第二部分
用 readint (自定義函數(shù))讀入三位二進制凑懂,len煤痕。如果len為 0 則跳出循環(huán)。然后到下一層接谨。reading 的讀入可以類比十進制杭攻,我們總是把用來的數(shù) * 10 再加上剛讀入的低位加上來獲得新值;2進制同理疤坝,只是換成了乘以 2兆解。
第三部分
用 reading(len) 讀入len位的二進制轉(zhuǎn)十進制 v,如果為2^len - 1 則跳出循環(huán)跑揉,否則直接打印 code[len][v]锅睛。因為 len 位全 1 的 2 進制 +1 剛好等于 2 ^(len+1) 。
筆者的失誤
一開始寫 readcode 最后的返回值寫成了0历谍,所以wa了....
顯然是因為我沒有考慮如果把 code 讀滿了的情況现拒。
代碼
#include <stdio.h>
#include <string.h>
int code[8][1<<8];
int readint(int l); //讀入一個l位的二進制并返回十進制
int readchar(); //跳過回車讀入
int readcodes(); //讀入編碼頭
int main() {
#ifdef TEST
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif // TEST
while (readcodes()) {
for (;;) {
int len = readint(3);
if (len == 0) break;
for (;;) {
int v = readint(len);
if (v == (1 << len) - 1) break;
putchar(code[len][v]);
}
}
printf("\n");
}
return 0;
}
int readint(int len){
int v = 0;
while (len--) v = v * 2 + readchar() - '0';
return v;
}
int readchar(){
for (;;) {
int ch = getchar();
if (ch != '\n' && ch != '\r') return ch;
}
}
int readcodes(){
for (int i = 0; i < 8; i++)
memset(code[i], 0, sizeof(code[i]));
code[1][0] = readchar();
for (int len = 2; len < 8; 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;
}