日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

《算法竞赛入门经典》 例题 4-4 信息编码 (Message Decoding,ACM,ICPC World Finals 1991,UVa 213)

發(fā)布時(shí)間:2024/4/30 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《算法竞赛入门经典》 例题 4-4 信息编码 (Message Decoding,ACM,ICPC World Finals 1991,UVa 213) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原題及翻譯

Some message encoding schemes require that an encoded message be sent in two parts.
某些消息編碼方案要求將編碼的消息分為兩部分發(fā)送。
The first part, called the header, contains the characters of the message.
第一部分稱為標(biāo)題,包含消息的字符。
The second part contains a pattern that represents the message.
第二部分包含表示消息的模式。
You must write a program that can decode messages under such a scheme.
您必須編寫一個(gè)程序,在這種方案下可以解碼消息。
The heart of the encoding scheme for your program is a sequence of “key” strings of 0’s and 1’s as follows:
程序編碼方案的核心是一系列0和1的“鍵”字符串,如下所示:
0, 00, 01, 10, 000, 001, 010, 011, 100, 101, 110, 0000, 0001, . . . , 1011, 1110, 00000, . . .
The first key in the sequence is of length 1, the next 3 are of length 2, the next 7 of length 3, the next 15 of length 4, etc.
序列中的第一個(gè)鍵為長(zhǎng)度1,下一個(gè)3為長(zhǎng)度2,下一個(gè)7為長(zhǎng)度3,下一個(gè)15為長(zhǎng)度4等。
If two adjacent keys have the same length, the second can be obtained from the first by adding 1 (base 2).
如果兩個(gè)相鄰鍵的長(zhǎng)度相同,則可以通過(guò)添加1(基2)從第一個(gè)鍵獲取第二個(gè)鍵。
Notice that there are no keys in the sequence that consist only of 1’s.
注意,序列中沒(méi)有只包含1的鍵。
The keys are mapped to the characters in the header in order.
鍵按順序映射到頭中的字符。
That is, the first key (0) is mapped to the first character in the header, the second key (00) to the second character in the header, the kth key is mapped to the kth character in the header.
也就是說(shuō),第一個(gè)鍵(0)映射到頭中的第一個(gè)字符,第二個(gè)鍵(00)映射到頭中的第二個(gè)字符,第k個(gè)鍵映射到頭中的第k個(gè)字符。
For example, suppose the header is:
例如,假設(shè)頭是:
AB#TANCnrtXc
Then 0 is mapped to A, 00 to B, 01 to #, 10 to T, 000 to A, …, 110 to X, and 0000 to c.
然后0映射到A,00到B,01到#,10到T,000到A,…,110到X,0000到c。
The encoded message contains only 0’s and 1’s and possibly carriage returns, which are to be ignored.
編碼的消息只包含0和1,并且可能包含回車,這將被忽略。
The message is divided into segments.
消息分為段。
The first 3 digits of a segment give the binary representation of the length of the keys in the segment.
段的前3位數(shù)字給出段中鍵的長(zhǎng)度的二進(jìn)制表示。
For example, if the first 3 digits are 010, then the remainder of the segment consists of keys of length 2 (00, 01, or 10).
例如,如果前3位是010,則段的其余部分由長(zhǎng)度為2(00、01或10)的鍵組成。
The end of the segment is a string of 1’s which is the same length as the length of the keys in the segment.
段的末尾是一個(gè)1的字符串,其長(zhǎng)度與段中鍵的長(zhǎng)度相同。
So a segment of keys of length 2 is terminated by 11.
因此,長(zhǎng)度為2的鍵段以11結(jié)尾。
The entire encoded message is terminated by 000 (which would signify a segment in which the keys have length 0).
整個(gè)編碼的消息以000結(jié)尾(這表示密鑰長(zhǎng)度為0的段)。
The message is decoded by translating the keys in the segments one-at-a-time into the header characters to which they have been mapped.
通過(guò)將段中的鍵一次轉(zhuǎn)換為它們映射到的頭字符,可以對(duì)消息進(jìn)行解碼。

Input

輸入
The input file contains several data sets.
輸入文件包含多個(gè)數(shù)據(jù)集。
Each data set consists of a header, which is on a single line by itself, and a message, which may extend over several lines.
每個(gè)數(shù)據(jù)集包括一個(gè)單獨(dú)在一行上的頭和一條可能擴(kuò)展到多行上的消息。
The length of the header is limited only by the fact that key strings have a maximum length of 7 (111 in binary).
頭的長(zhǎng)度僅受以下事實(shí)的限制:鍵字符串的最大長(zhǎng)度為7(二進(jìn)制為111)。
If there are multiple copies of a character in a header, then several keys will map to that character.
如果一個(gè)標(biāo)題中有一個(gè)字符的多個(gè)副本,那么幾個(gè)鍵將映射到該字符。
The encoded message contains only 0’s and 1’s, and it is a legitimate encoding according to the described scheme.
編碼的消息只包含0和1,根據(jù)所描述的方案,它是合法的編碼。
That is, the message segments begin with the 3-digit length sequence and end with the appropriate sequence of 1’s.
也就是說(shuō),消息段以3位長(zhǎng)度序列開(kāi)始,以1的適當(dāng)序列結(jié)束。
The keys in any given segment are all of the same length, and they all correspond to characters in the header.
任何給定段中的鍵都具有相同的長(zhǎng)度,并且它們都對(duì)應(yīng)于頭中的字符。
The message is terminated by 000.
消息被000終止。
Carriage returns may appear anywhere within the message part.
回車可以出現(xiàn)在消息部分的任何位置。
They are not to be considered as part of the message.
它們不應(yīng)被視為消息的一部分。

Output

輸出
For each data set, your program must write its decoded message on a separate line.
對(duì)于每個(gè)數(shù)據(jù)集,程序必須將其解碼后的消息寫在單獨(dú)的行上。
There should not be blank lines between messages.
消息之間不應(yīng)該有空行。
Sample input
樣例輸入
TNM AEIOU
0010101100011
1010001001110110011
11000
$#**
0100000101101100011100101000
Sample output
樣例輸出
TAN ME
##*$

思路分析

代碼分析

1.首先是讀取編碼并將編碼存儲(chǔ)的函數(shù)。
在使用全局變量中的數(shù)組時(shí),應(yīng)該先把數(shù)組清零:

memset(code,0,sizeof(code));

由于編碼頭自身占一行,所以可以用readchar()讀取第一個(gè)字符,而用普通的getchar()讀取剩下的字符,知道換行符為止:

code [1][0]=readchar();

而readchar()是這樣定義的:

int readchar() {//跨行讀字符。for(;;){int ch=getchar();if(ch!='\n'&&ch!='\r') return ch; //一直讀到非換行符為止。//也就是說(shuō),當(dāng)讀到不是換行符的時(shí)候,返回ch的內(nèi)容。} }

可以用codes[len][value]這個(gè)二維數(shù)組來(lái)表示一個(gè)編碼,其中l(wèi)en是編碼長(zhǎng)度,value是編碼對(duì)應(yīng)的十進(jìn)制值。二進(jìn)制中,8位最大整數(shù)就是8個(gè)1,即28-1,用移位運(yùn)算符表示就是(1<<8)-1。

int readcodes() {//讀取編碼。memset(code,0,sizeof(code));code [1][0]=readchar();//直接調(diào)到下一行開(kāi)始讀取。如果輸入已經(jīng)結(jié)束,會(huì)讀到EOF。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; }

2.然后是將二進(jìn)制轉(zhuǎn)化為十進(jìn)制的函數(shù),這里采用的二進(jìn)制轉(zhuǎn)十進(jìn)制是一次添加一位的運(yùn)算方式,每次乘以2,比如說(shuō):1012=((1*2)+0)*2+1=5。

int readint(int c) {//讀取c位二進(jìn)制字符(即0和1),并轉(zhuǎn)化為十進(jìn)制整數(shù)。int v=0;while(c--) v=v*2+readchar()-'0';return v; }

3.最后就是主函數(shù)了,讀入數(shù)據(jù),調(diào)用函數(shù)做處理,輸出結(jié)果。
用一個(gè)無(wú)限循環(huán)連續(xù)處理數(shù)據(jù):

for(;;)

要讀入開(kāi)頭的三個(gè)數(shù)字代表小節(jié)中每個(gè)編碼的長(zhǎng)度:

int len=readint(3);

然后再來(lái)一個(gè)無(wú)限循環(huán)處理代表編碼長(zhǎng)度后邊、結(jié)束標(biāo)志前邊的數(shù)字:

for(;;){int v=readint(len);//v是len十進(jìn)制位的二進(jìn)制數(shù)轉(zhuǎn)化為十進(jìn)制數(shù)后的數(shù)if(v==(1<<len)-1) break;//當(dāng)小節(jié)編碼結(jié)尾標(biāo)志11…1出現(xiàn)時(shí),跳出當(dāng)前循環(huán)putchar(code[len][v]);}}

把這些組合起來(lái)就是主函數(shù):

int main() {while(readcodes()){//無(wú)法讀取更多編碼頭時(shí)時(shí)退出。for(;;){int len=readint(3);if(len==0) break;//即結(jié)尾標(biāo)志:000for(;;){int v=readint(len);if(v==(1<<len)-1) break;putchar(code[len][v]);}}putchar('\n');}return 0; }

完整代碼

#include <stdio.h> #include <string.h> int code[8][1<<8]; //1<<8表示2的八次方 int readchar() {//跨行讀字符。for(;;){int ch=getchar();if(ch!='\n'&&ch!='\r') return ch; //一直讀到非換行符為止。//也就是說(shuō),當(dāng)讀到不是換行符的時(shí)候,返回ch的內(nèi)容。} } int readint(int c) {//讀取c位二進(jìn)制字符(即0和1),并轉(zhuǎn)化為十進(jìn)制整數(shù)。int v=0;while(c--) v=v*2+readchar()-'0';return v; } int readcodes() {//讀取編碼。memset(code,0,sizeof(code));code [1][0]=readchar();//直接調(diào)到下一行開(kāi)始讀取。如果輸入已經(jīng)結(jié)束,會(huì)讀到EOF。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; } int main() {while(readcodes()){//無(wú)法讀取更多編碼頭時(shí)時(shí)退出。for(;;){int len=readint(3);if(len==0) break;for(;;){int v=readint(len);if(v==(1<<len)-1) break;putchar(code[len][v]);}}putchar('\n');}return 0; }

結(jié)語(yǔ)

大道至簡(jiǎn),最簡(jiǎn)單的代碼也許難以理解,但這正是算法的美妙之處。

每天磕一道ACM 大年初一打卡

總結(jié)

以上是生活随笔為你收集整理的《算法竞赛入门经典》 例题 4-4 信息编码 (Message Decoding,ACM,ICPC World Finals 1991,UVa 213)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。