UVA - 213 - Message Decoding
所用平台 macOS IDE:CodeRunner (macOS的xcode在更新到 15B3 在非转译模式下还是有问题,只能继续用coderunner) 语言:C++ 11
作者废话很多所以想直接看答案请拉到底部
本文给出答案已成功在VOJ AC。
题目详情:
NOTICE:因为我是在MarkDown编辑器里面写的所以可能特殊字符会出现问题,推荐各位有条件可以去官网或者VOJ(我还是更喜欢VOJ),而且官网排版非常优秀
UVA官网点我传送
VOJ点我传送
(英文)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 that represents 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 as follows:
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. If two adjacent keys have the same length, the second can be obtained from the 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 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. 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’s which is the same length as the length of the keys in the segment. So a segment of keys of length 2 is terminated 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 segments one-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 message contains 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 as part of the message.Output
For each data set, your program must write its decoded message on a separate line. There should not be blank lines between messages.
Sample input
TNM AEIOU 此处为编码头
0010101100011
1010001001110110011
11000 从编码头到此为编码文本
$#**\
0100000101101100011100101000
Sample output
TAN ME
##*$
题目解析
其实本题在纯英文环境下十分不好理解,我也是借助Google翻译才能勉强看懂,在本处引用算法经典入门经典(第二版)第四章P83页例题4.4的中文解释:(ios15扫描太好用了!!!吹爆除了极个别大小写有问题,另外简直了!)
考虑下面的 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 对应又,0000对应C。接下来是编码文本(可能由多行组成,你应当把它们拼成一个长长的 01串)。编码文本由多个小节组成,每个小节的前3个数字代表小节中每个编码的长度(用二进制表示,例如 010 代表长度为 2),然后是各个字符的编码,以全1结束(例如,
编码长度为2的小节以 11结束)。编码文本以编码长度为 000 的小节结束。
例如,编码头为$#补,编码文本为 0100000101101100011100101000,应这样解码:
** 010(编码长度为 2)00(#)00(#)10()11(小节结束)011(编码长度为 3)000(111(小节结束)001(编码长度为 10($)1(小节结束)000(编码结束) **
具体要求分析:
首先本题目的核心内容就是解码
每个编码都有编码头 + 编码文本组成
其中编码头为任意给定的文本
编码文本又分为多个小节
小节中前三个数字代表的这个小节的文本长度 以 2进制给出范围(1-7)后将这三个数字统称为小节头,
随后跟上各个字符的编码(长度由小节头确定)每个小节都以该小节长度的连续1字符床结束 (例如 小节头表示2 就以 11)结束
每串编码以000作为最后结束 该句话等价于 当编码头为 0 时结束
解题过程
框架搭建
首先我们先明确整体程序的框架 (字比较丑)
1.首先第一个阶段读入编码头阶段 我们发现在题目给出的示例文档中 中间有一个空格,如果直接使用 scanf函数的%s那会导致读到空格处停下就会出现问题,所以我们可以使用正则表达式让他在读到回车时停止
while (~scanf("%[^\n]",headercode)) {
2.读入编码头设计到读入和转换问题 我们专门定一个函数(可处理1~7长度)而头只有3位 所以只需要把参数改为3就可以了