zoukankan      html  css  js  c++  java
  • 算法习题---4.4信息解码(UVa213)

    一:题目

    消息编码方案要求在两个部分中发送一个被编码的消息。第一部分:称为头,包含消息的字符。第二部分包含一个模式 
    表示信息。你必须写一个程序,可以解码这个消息。

    (一)题目详细

    你的程序的编码方案的核心是一个序列的“0和1”的字符串 。
    
    0, 00, 01, 10, 000, 001, 010, 011, 100, 101, 110, 0000, 0001, . . . , 1011, 1110, 00000, . . .(对应数字个数n,则表示的编码为2^n-1个)
    
    序列中长度为1的1个,长度为2的3个,长度为3的7个,长度为4的15个。如果相邻两个具有相同的长度,第二可从第一个加1(2进制)。注意有序列中没有全都是1的串。
    
    键被映射到标题中的字符。也就是说,第一个键(0)映射在标题的第一个字符,第二键(00)在头的二字符,k键映射到标头中的k个字符。

    (二)案例

    例如,假设标题是:AB#TANCnrtXc  (可以包含空格)
    
    然后0映射到A,00映射到B,01映射到#,10映射到T,000映射到A,…,110映射到X,0000映射到c.
    
    该编码的信息包含0和1的和可能的回车,这是被忽略。消息分为段。一个段的前3位数字为二进制表示在段的键的长度。例如,如果前3位数字为010,则其余该段由长度为2(0001,或10)。段的结束是1的字符串
    在段中的键长度相同。因此一段长度2的键是终止11。整个编码的信息被000终止(这将意味着一段段其中的按键有0个)。通过将该段中的键进行翻译,该消息被解码的标题字符已被映射。

    (三)输入

    输入文件包含多个数据集。
    每个数据集包含一个标题,这是在一个单独的行就其本身而言,和一个消息,它可能会延续几行。
    头的长度(由三个数据位表示,0-7--->最大长度为七)是有限的唯一的事实,有一个关键字符串的最大长度为7(111的二进制)。--->(由于最大长度为7,所以所表示的最大编码数为2^7-1
    如果有多个在头一个字符的副本,然后几个键将映射到字符。
    编码信息仅包含0和1的,这是一个合法的编码,根据所描述的计划。那是,信息段的开始与适当的序列的序列长度和位数1,在任何给定的段的键都是相同的长度,并且它们都对应于字符标题。
    该消息以000终止
    TNM AEIOU
    0010101100011
    1010001001110110011    //允许换行
    11000  //这才是结束
    $#**
    0100000101101100011100101000  //结束

    (四)输出

    TAN ME
    
    ##*$

    二:代码实现

    //信息解码,所有信息都属于ASCII码中
    void Save_Encode(char Code_Header[MAX_LEN],char Encode[7][128],int CHT_Status)
    {
        //开始向编码中存放数据
        //获取编码头--注意含有空格
    
        int ch,i=0;
        if (!CHT_Status)    //编码头没有获取
            while (1)
            {
                ch = getchar();
                Code_Header[i++] = ch;
                if (ch == '
    '||ch==EOF)
                    break;
            }
    
        //将编码头数据放入编码中--最重要
        int p,k = 0;
        for (i = 1; i <= 7; i++)
        {
            p = pow(2.0, i*1.0) - 1;
            for (int j = 0; j < p; j++)
                if (Code_Header[k] != '
    ')
                    Encode[i][j] = Code_Header[k++];
                else
                    return;
        }
    }
    //获取编码文本到Code_Text
    int
    Save_CodeText(char Code_Text[MAX_LEN], char Code_Header_Temp[MAX_LEN]) { int ch, i; while (1) { memset(Code_Header_Temp, 0, sizeof(Code_Header_Temp)); //获取一行到Code_Header_Temp i = 0; while (1) { ch = getchar(); Code_Header_Temp[i++] = ch==EOF?' ':ch; if (ch == ' '||ch==EOF) break; } if (Code_Header_Temp[0] != '1' && Code_Header_Temp[0] != '0') return 1; //将临时数据连接到Code_Text中 if (strlen(Code_Text)>0) Code_Text[strlen(Code_Text)-1] = 0; strcat(Code_Text, Code_Header_Temp); } return 0; }
    //获取指定个数二进制文本的数值
    int getVal(char* codeText,int n)
    {
        int val = 0;
        for (int i = n - 1; i >= 0;i--)
        {
            int k = 1;
            for (int j = 1; j <= i; j++)
            {
                k *= 2;
            }
            val += (*codeText-'0')*k;
            codeText++;
        }
        return val;
    }
    //处理数据,进行输出
    void
    Deal_CodeData(char Encode[][128], char* Code_Text) { int len,val,chk,k=0; while (1) { //找到编码长度 len = getVal(&Code_Text[k], 3); Code_Text += 3; //步长向后移动3个 if (len == 0) //3个0退出 return; chk = pow(2.0, len*1.0) - 1; //根据长度,获取值 while (1) { val = getVal(Code_Text, len); Code_Text += len; if (val == chk) break; //去对应位置找编码数据 printf("%c", Encode[len][val]); } } }
    void func03()
    {
        FILE* fi = freopen("data.in", "r", stdin);
        freopen("data.out", "w", stdout);
    
        //因为前三位表示长度,所以最长为7位其中七位编码最大为1111110可以表示2^7-1个数所以将列数设置为2^7=128
        char Encode[8][128];    //操作二维数组,我们直接从1开始,忽略0带来的麻烦
        //注意:每行只有2^n - 1 个有效
    
        char Code_Header[MAX_LEN];    //存放编码头
        char Code_Text[MAX_LEN];    //存放编码文本
    
        char Code_Header_Temp[MAX_LEN];    //存放有可能的编码头
    
        int CHT_Status=0;    //是否从临时数组中读取编码头
    
        memset(Code_Header_Temp, 0, sizeof(Code_Header_Temp));
        
        //开始进行读取处理数据
        while (!feof(fi))
        {
            memset(Code_Text, 0, sizeof(Code_Text));
            memset(Encode, 0, sizeof(Encode));
            memset(Code_Header, 0, sizeof(Code_Header));
    
            //将编码头数据保存到编码数组中
            if (CHT_Status)
                strcpy(Code_Header, Code_Header_Temp);
    
            Save_Encode(Code_Header, Encode,CHT_Status);
    
            //获取编码文本--文本可能不在同一行(难点)
            //方法:一次获取一个字符
            CHT_Status = Save_CodeText(Code_Text,Code_Header_Temp);
    
            //开始处理数据,并打印出来
            Deal_CodeData(Encode,Code_Text);
            printf("
    ");
        }
    
        freopen("CON", "r", stdin);
        freopen("CON", "w", stdout);
    }
  • 相关阅读:
    columns布局应用场景
    flex速记
    css属性选择器模糊匹配
    ydui的rem适配方案
    vscode搜索失效问题
    ESP8266 超声波测距模块HC-SR04
    树莓派PICO Wifi 无线网卡 esp82666接线图
    查看数据库容量大小
    面试官问我JVM内存结构,我真的是
    深入浅出Java内存模型
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10837824.html
Copyright © 2011-2022 走看看