1. 程式人生 > >資訊解碼

資訊解碼

題目:

考慮下面的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;
}