資訊解碼
阿新 • • 發佈:2018-12-22
題目:
考慮下面的01串序列:
0,00,01,10,000,001,010,011,100,101110,0000,0001,...,1101,1110,00000,...
首先是長度為1的串,然後是長度為2的串,依此類推。如果看成二進位制,相同長度的後一個串等於前一個串加1,。注意上述序列中不存在全為1的串。
你的任務是編寫一個解碼程式。首先輸入一個編碼頭(例如 AB#TANCnrtXc),則上述序列的每個串依次對應編碼頭的每個字元。例如,0對應A,00對應B,01對應#,...,110對應X,0000對應c。接下來是編碼文字(可能由多行文字組成,你應當把他拼成一個長長的01串)。編碼文字由多個小節組成,每個小節的前3個數字代表每個編碼的長度(用二進位制表示,例如010代表長度為2),然後是各個字元的編碼,以全1結束(例如,編碼長度為2的小節以11結束)。編碼文字以編碼長度為000的小節結束。
例如,編碼頭為$#**\,編碼文字為0100000101101100011100101000,應這樣編碼:010(編碼長度為2)00(#)10(*)11(小節結束)011(編碼長度為3)000(\)111(小節結束)001(編碼長度為1)0($)1(小節結束)000(編碼結束)。
分析:
還記得二進位制碼?有了二進位制,就不必以字串的形式儲存這一大串編碼了,只需把編碼理解成二進位制,用(len,value)這個二元組來表示一個編碼,其中len是編碼長度,value是編碼對應的十進位制值。如果用codes[len][value]儲存這個編碼所對應的字元,則主程式看上去應該是這個樣子的。
回答:
#include<stdio.h> #include<string.h> //使用memset int readchar() { ... } int readint() { ... } int main() { while(readcodes()) { //無法讀取更多的編碼頭時退出 for(,,) { int len = readint(3); if(len == 0) break; //printf(“len=%d\n”,len); for(;;) { int v = readint(len); //printf("v=%d\n",v); if(v == (1<<len) - 1) break; putchar(code[len][v]); } } putchar('\n'); } return 0; } int readchar() { for(;;) { int ch = getchar(); if(ch != '\n' && ch != '\r') return ch; //一直讀到非換行符為止 } } int readint() { int v=0; while(c--) v=v*2+readchar() - '0'; return v; }