信息解码(Message Decoding, ACM/ICPC World Finals 1991, UVa 213)

本文介绍了一个编程问题,要求编写一个解码程序,将给定的编码头映射到特定的01串序列,同时处理getchar输入中的回车问题。主要涉及函数如readchar、readint和readcodes,用于解析字符长度和二进制数值。
摘要由CSDN通过智能技术生成

考虑下面的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的小节结束。


这是遇到的第一个对我来说比较难的题,花了两三小时写出来的,而且有一点错误。getchar输入时,循环输入时回车键不易处理,添加一个判断语句控制忽略回车。因此加一个readchar函数。

最终代码是没问题的,感觉还可以再改进。
重点是readint函数,读取c个长度的二进制字符,返回出整型十进制数字。
redecodes读取给出的编码头

#include<stdio.h>
#include<iostream>
#include<String.h>
#define MAXN 81
using namespace std;

char code[8][1<<8] = {0};//code[len][value] len是长度,value是对应十进制的值 

int readchar() {
	for(;;) 
	{
		int ch = getchar();
		if(ch != '\n' && ch != '\r') return ch; //一直读到非换行符为止
	}
} 
int readint(int c) //读取 c位二进制字符 
{
	int v = 0;
	
	while(c--) 
	{
		
		v = v + (1<<c) * (readchar() - '0');
	}
	return v; 
}
int readcodes() // 读取编码头 保存到code[][] 
{
	char head[MAXN];
	int i = 1, count = 0;
	scanf("%s", head);
	while(i <= strlen(head))
	{
		int j = 0;
		while(i <= strlen(head) && j < (1<<i)-1) // j< i的平方-1 
		{
			code[i][j++] = head[count++];
		}
		i++;
    }
    return 1;
}

 

int main()
{
	while(readcodes()) // 循环读取编码头 
	{
		printcodes();
		while(1)
		{
			int len = readint(3); // 读取前三位 转成二进制表示长度
			if(len == 0) break; 
			while(1)
			{
				int v = readint(len); // v代表每次读取len位的值 
				if(v == (1 << len)-1) break; // (1<<len)-1表示1左移len位后减一得到全一。或者可以理解为1*2的len次方减一
				putchar(code[len][v]); // 打印出 (len, v)的字母值 
			}
		}
		putchar('\n'); 
		memset(code, 0, sizeof(code));
	}
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

复习你给的温柔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值