题意:
1. 首先输入编码头,即一串字符串
2. 接下来时只有0和1的串,要求就是对串进行操作然后输出对应的编码串
3. 每次编码先用三个字符计算二进制和判断接下来的串时多少个字符为一个编码
4. 每次编码遇到全为1的时候结束进行下一次串长判断(即重复3),直到串长判断为0时结束本次编码
5. 根据二进制规则对编码头进行一一对应
6. 0对应1,00对应2,01对应3,10对应4,(不存在全为1的串,全为1的串表示结束),000对应5,001对应6,……
7. 由于二进制111=7,所以经过计算这个编码头最长也就247个字符,开个300的数组足矣
8. PS:01串中随机出现的回车不纳入字符判断(即需要跳过)
思路:
1. 先用三个字符判断接下来的编码串长sum
2. 然后利用sum判断前置有多少位数flag
3. 接下来对sum长度的串进行二进制和计算出num
4. flag+num就是对应的编码字符的下标
5. 遇到sum=0时结束本次编码,并等待下一个编码头的输入
6. 每次编码结束要记得清空缓冲区,不然会影响下一次的编码
我的AC代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
char s[300];
int main()
{
//freopen("input.txt","r",stdin);
char ch;
int sum,flag,q,num;
while(gets(s))
{
while(1)
{
//测待用长度
sum=0;
for(int i=2; i>=0; i--)
{
ch=getchar();
if(ch=='\n') //跳过回车
i++;
else if(ch=='1')
sum+=pow(2,i);
}
//如果长度为0,再见
if(sum==0)
break;
//处理前置位置
else if(sum==1)
flag=0;
else if(sum==2)
flag=1;
else if(sum==3)
flag=4;
else if(sum==4)
flag=11;
else if(sum==5)
flag=26;
else if(sum==6)
flag=57;
else if(sum==7)
flag=120;
q=pow(2,sum)-1;
//这里开始循环输出对应长度代表的字符
//直到全为1时结束进入下一次编码判断
while(1)
{
num=0;
for(int i=sum-1; i>=0; i--)
{
ch=getchar(); //输入字符
if(ch=='\n') //跳过回车
i++;
else if(ch=='1')
num+=pow(2,i);
}
//当长度sum的串全为1时结束
if(num==q)
break;
//按位置输出字符
else
printf("%c",s[flag+num]);
}
}
printf("\n");
//吃光缓冲区,为下一次的编码头输入做清空操作
while((ch = getchar()) != '\n' && ch != EOF);
}
return 0;
}