算法习题---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(00,01,或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 == ‘\n‘||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] != ‘\n‘)
                Encode[i][j] = Code_Header[k++];
            else
                return;
    }
}
//获取编码文本到Code_Textint 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?‘\n‘:ch;
            if (ch == ‘\n‘||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("\n");
    }

    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
}

原文地址:https://www.cnblogs.com/ssyfj/p/10837824.html

时间: 2024-08-11 04:04:13

算法习题---4.4信息解码(UVa213)的相关文章

把vux中的@font-face为base64格式的字体信息解码成可用的字体文件

在最近移动端项目中用到了vux,感觉用着还习惯,当把vux使用到PC端的时候出现了IE浏览器出现,这样的错误信息: CSS3114: @font-face 未能完成 OpenType 嵌入权限检查.权限必须是可安装的. 文件: UwCtGsNCf5NCQ0N.... 然后在IE浏览器页面中的字体图标就没有显示. 原来在vux中weiui_font.less文件中,如下写法: @font-face { font-weight: normal; font-style: normal; font-fa

UVA213信息解码

<算法竞赛入门经典>第四章函数和递归中的题目,考察了自定义函数应用和二进制相关内容.(个人认为考察二进制相关知识占多). 题意:给一个编码头和一串编码(编码可以换行),编码头根据以下规则对应编码{  考虑下面的01串:  0,00,01,10,000,001,010,101,110,0000,0001.....首先是长度为1的串,然后是长度为二的串,以此类推.并且每一段长度的数字从0到(1<<n)-1(第n段)排列,即题目中所说不包括全为1的串. 编码文本由多个小节组成,每小节前三

加密狗复制备份 订制写狗程序 算法注册机 OEM信息 二次封装

加密狗复制备份.模拟  行业软件批发零售 定制写狗程序.注册机 软件破解 逆向工程   酒店客房管理.餐饮娱乐管理.美容美发管理.汽车行业.会员管理.医疗软件.客户管理.财务进销存系统 .OA办公 .服装设计 等大量行业软件批发零售 合作联系QQ: 844256300 =========================================================================================== 企发会员积分系统3.5 冠唐仓库管理网络版 凤

2015/10/13 算法习题:最大子列和问题

已经正式开始学习数据结构和算法,先学了网易云课堂上的浙江大学的数据结构课,是陈越和何钦铭上的,了解了什么是数据结构和算法后,学习了一些时间空间复杂度分析的技巧,结合之前马虎掌握的学习,先从简单的题目入手学习. 题目是这样的: 给定了一个n个整数组成的序列,求它各个子列中,子列和最大的值. 输入:输入n个整数组成的序列 要求输出最大子列和. 示例: 输入: -2 11 -4 13 -5 -2 输出: 20 做出这题的难度不是很大,至少很容易可以做到暴力求解,然而暴力求解的时间复杂度是很大的. 我用

排序算法习题汇总

1.冒泡排序 对于一个int数组,请编写一个冒泡排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] class BubbleSort { public: int* bubbleSort(int* A, int n) { // write code here for(int i=0;i<n-1;i++){ int k=0; for(int j=0;j<n-i-1;j++){ if(A[j]&

算法习题---线性表之单链表逆序打印

一:题目 逆序打印单链表中的数据,假设指针指向单链表的开始结点 二:思路 1.可以使用递归方法,来进行数据打印 2.可以借助数组空间,获取长度,逆序打印数组 3.若是可以,对链表数据使用头插法,逆序排列,然后正序打印即可 三:算法实现(这里使用方法一:递归实现简单易懂) #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define MAXSIZE 10 #define OK 1 #def

算法习题---线性表之单链表的查找

一:问题 已知一个带头结点的单链表,结点结构为(data,link)假设该链表只给出了头指针list,在不改变链表的前提下,设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数),若查找成功,算法输出该结点的data域的值,并返回1,否则,只返回0. 注意: 这里的链表中没有给出链表长度哟 二:思路 设置两个指针p.q,分别指向该链表的第一个元素(头结点的下一个元素)和头结点,一个整数num(初值为1),p向后移动一个位置num值加1,如果num值大于k,则p,q一起移动,p移

算法习题---线性表之数组实现循环移动

一:问题 设将n(n>1)个整数存放到一维数组R中,试设计一个在时间和空间两方面都尽可能高效的算法,将R中保存的序列循环左移p(0<p<n)个位置,即把R中的数据序列由(x0,x1,…,xn-1)变换为(xp,xp+1,…,xn-1,x0,x1,…,x). 二:思考 要实现R中序列循环左移P个位置,只需先将R中前P个元素逆置,再将剩下的元素逆置,最后将R中所有的元素再整体做一次逆置操作即可,本题算法描述如下: (一)步骤一:将前P个元素逆置 (二)步骤二:将后P个元素逆置 (三)步骤三:

算法习题---字符串的全排序列

一:什么是全排列 排列:从n个元素中任取m个元素,并按照一定的顺序进行排列,称为排列: 全排列:当n==m时,称为全排列: 比如:集合{ 1,2,3}的全排列为: { 1 2 3} { 1 3 2 } { 2 1 3 } { 2 3 1 } { 3 2 1 } { 3 1 2 } 我们可以将这个排列问题画成图形表示,即排列枚举树,比如下图为{1,2,3}的排列枚举树,此树和我们这里介绍的算法完全一致: 二:全排列实现思路 (1)n个元素的全排列=(n-1个元素的全排列)+(另一个元素作为前缀):