Message Decoding——Uva_213

我怎么说,这道题我就是纯粹没读懂题。。。头脑宛如拧在一起的麻花。。。英语水平有待提高。

Some message encoding schemes require that an encoded message be sent in two parts. The first part,called the header, contains the characters of the message. The second part contains a pattern thatrepresents the message. You must write a program that can decode messages under such a scheme.

The heart of the encoding scheme for your program is a sequence of “key” strings of 0’s and 1’s asfollows:

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, thenext 15 of length 4, etc. If two adjacent keys have the same length, the second can be obtained fromthe first by adding 1 (base 2). Notice that there are no keys in the sequence that consist only of 1’s.

The keys are mapped to the characters in the header in order. That is, the first key (0) is mappedto the first character in the header, the second key (00) to the second character in the header, the kthkey is mapped to the kth character in the header. For example, suppose the header is:

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.

The encoded message contains only 0’s and 1’s and possibly carriage returns, which are to be ignored.The message is divided into segments. The first 3 digits of a segment give the binary representationof the length of the keys in the segment. For example, if the first 3 digits are 010, then the remainderof the segment consists of keys of length 2 (00, 01, or 10). The end of the segment is a string of 1’swhich is the same length as the length of the keys in the segment. So a segment of keys of length 2 isterminated by 11. The entire encoded message is terminated by 000 (which would signify a segmentin which the keys have length 0). The message is decoded by translating the keys in the segmentsone-at-a-time into the header characters to which they have been mapped.

Input

The input file contains several data sets. Each data set consists of a header, which is on a single lineby itself, and a message, which may extend over several lines. The length of the header is limitedonly by the fact that key strings have a maximum length of 7 (111 in binary). If there are multiplecopies of a character in a header, then several keys will map to that character. The encoded messagecontains only 0’s and 1’s, and it is a legitimate encoding according to the described scheme. That is,the message segments begin with the 3-digit length sequence and end with the appropriate sequence of1’s. The keys in any given segment are all of the same length, and they all correspond to characters inthe header. The message is terminated by 000.

Carriage returns may appear anywhere within the message part. They are not to be considered aspart of the message.

Output

For each data set, your program must write its decoded message on a separate line. There should notbe blank lines between messages.

Sample input

TNM AEIOU
0010101100011
1010001001110110011
11000
$#**\
0100000101101100011100101000

Sample output

TAN ME

##*\$ 


其实说白了就是,先给你一段英文,然后每一个英文对应一个编码,只不过是分过组的,1个英文为一组,2个英文为一组,4个英文为一组...2^n个英文为一组,每一组的标记从零开始到2^n-1。然后给你了一个编码文本,编码文本分为若干个小节,每一个小节的头三个数字代表这一个小节的长度,在这一小节的末尾是小节长度个1。于是题目要求给一段01串,求它的实际编码。

感觉挺绕的。一个思维难点在于,我知道这个小节的长度了,我也知道这个小节停在啥地方了,但是中间有一大堆0101之类的玩意儿我该怎么分啊......想到这个就真的...心态崩了。


书上的解法是这个样子的,他把编码理解成了二进制,同时用(len, value)来表示一个编码,value是编码对应的十进制,用codes[len][value]保存这个编码所对应的字符。(oh no, 我还是没有懂这到底是啥个意思......所以我决定看代码......)


#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int readchar()
{
    for(;;)
    {
        int ch = getchar();
        if(ch != '\n' && ch != '\r')
            return ch;
    }
}

int readint(int c)
{
    int v = 0;
    while(c--)
        v = v * 2 + readchar() - '0';
    return v;
}

int code[8][1<<8];

int readcodes()
{
    memset(code, 0, sizeof(code));//清空数组
    code[1][0] = readchar();//直到调到下一行开始读取。如果输入已经结束,会读到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())//无法读取更多编码头时退出
    {
        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;
}

小声逼逼几句......

其实书本看到这里我觉得书上的函数好多呀,一点点东西都要使用函数感觉超麻烦的说。。。

然而仔细想想的话,我觉得这本书真的经典,因为这种写法培养了模块化的思想,也就是分块。

将每一个小小的作用都写成函数,不仅调用时条理清晰,而且在以后完成大型难题的时候有绝佳的作用。

同时对于模块化编程的思想也有进一步加深。

学到了。想lrj等等一系列前辈低头致敬!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值