UVA 213 信息解码(二进制&位运算)

题意:

出自刘汝佳算法竞赛入门经典第四章。

考虑下面的01串序列:

0, 00, 01, 10, 000, 001, 010, 011, 100, 101, 110, 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(#)00(#)10(*)11(小节结束)011(编码长度为3)000(\)111(小节结束)001(编码 长度为1)0($)1(小节结束)000(编码结束)。

分析:

以后可以用一个函数去处理有换行的读入。

 1 int read()
 2 {
 3     char ch;
 4     while(1)
 5     {
 6        ch =  getchar();
 7        if(ch != '\r' && ch != '\n')
 8         return ch;
 9     }
10 }

可以用这个函数去处理二进制转换十进制

1 int btod(int len)
2 {
3     int v=  0;
4     while(len--)
5     {
6         v = v * 2 + read() - '0';
7     }
8     return v;
9 }

然后注意读入完的代码转换就行 1<<n 等价于 2的n次方。 然后长度为n的编码最多可以存1<<n - 1 个数, 因为全是1的序列是不存在的。

最后放上代码#include <bits/stdc++.h>

using namespace std;
char input[1<<10];
char code[8][1<<8];
int codelen;
int read()
{
    char ch;
    while(1)
    {
       ch =  getchar();
       if(ch != '\r' && ch != '\n')
        return ch;
    }
}
int btod(int len)
{
    int v=  0;
    while(len--)
    {
        v = v * 2 + read() - '0';
    }
    return v;
}
int trans()
{
    int len = 1, cnt = 0;
    for(int i = 0; i < strlen(input); i++)
    {
        if(cnt < (1<<len)-1)
        {
            code[len][cnt++] = input[i];
        }
        else
        {
            cnt = 0;
            code[++len][cnt++] = input[i];
        }
    }
    return len;
}
void printtest()
{
       for(int i = 1; i <= codelen; i++)
        {
            int cnt = 0;
            while(code[i][cnt])
            {
                printf("%d %d %c\n",i,cnt,code[i][cnt]);
                cnt++;
            }
        }
}
int main()
{
//    freopen("1.txt","r",stdin);
    int ok = 40;
    while(gets(input))
    {
        memset(code,0,sizeof(code));
//        puts(input);
        codelen = trans();
//        printtest();
        while(1)
        {
            int len = btod(3);

            if(len == 0)
                break;
            while(1)
            {
                int b = btod(len);
                if(b == (1<<len)-1)
                {
                    break;
                }
                printf("%c", code[len][b]);
            }
        }
        printf("\n");
        getchar();
// 注意这个getchar 是吸收最后一个回车符用的 以后使用getchar()都要注意有没有回车符没被吸收 } }

 

posted @ 2017-05-12 14:36  Neord  阅读(435)  评论(0编辑  收藏  举报