UVa 213 Message Decoding (資訊解碼)
阿新 • • 發佈:2019-01-21
題意:
編寫一個解碼程式,對數字串進行解碼。
輸入第一行是一個解碼key。key從左到右每個字元分別對0,00,01,10,000,001,011,100,101,110,0000,0001,...,1101,1110,00000,.......不存在全是1的key。
長度為len的字元編碼有2^n-1個,而且恰好以二進位制方式從0到2^n-2遞增,而且字元編碼的最大長度為7,可以有2^7-1=127個字元。
需要解碼的文字由多個小節組成,每個小節的前三個數字代表小節中每個編碼的長度(用二進位制表示,例如010表示2),然後是該長度的不定個字元編碼,以全1結束,如長度為2時 '11'就表示結束,長度為000時表示需要編碼的文字結束。
#include <stdio.h> #include <string.h> //把編碼理解成二進位制,用(len,value)這個二元組來表示一個編碼,其中len是編碼長度,value是編碼對應的十進位制數值 //用code[len][value]儲存這個編碼所對應的字元 int code[8][1 << 8]; int readchar()//跨行讀字元 { while (1) { int ch = getchar(); if (ch != '\n'&&ch != '\r') return ch;//一直讀到非換行符為止 } } int readint(int c)//讀取c個二進位制字元。返回其這c個二進位制字元的十進位制值 { int v = 0; while (c--) { v = v * 2 + readchar() - '0'; } return v; } int readcodes()//讀取編碼 { memset(code, 0, sizeof(code)); code[1][0] = readchar(); //由於編碼頭自身佔一行,所以用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; } } } /* 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() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); while (readcodes())//無法讀取更多編碼頭時退出 { //printcodes(); while (1) { int len = readint(3);//每段前三個數字代表段中每個編碼的長度 if (len == 0) break; //printf("len=%d\n", len); while (1) { int v = readint(len); //printf("v=%d\n",v); if (v == (1 << len) - 1) break; putchar(code[len][v]); } } putchar('\n'); } return 0; }