这道题目我先来说一下的我自己的思路:
我自己的思路是,使用map<string, char>,构造出header与对应字符的映射关系,然后再进行扫描需要decode的字符,将这些字符转换成string形式,然后直接使用map[string],来得到输出
但是这样做有点问题,就是如何构造出所需要的header,即,所需要的0,00,01,10,等string,虽然不是不可以做,但是实际上非常的麻烦。
能够学到的一点就是,char[] 数组类型是可以转换为string类型的,这是非常重要的一点。
一会我会贴出我还没有完成的代码,这份代码中只缺少构造string的过程。
再来看汝佳大神的代码,他没有去直接构造这个映射关系,反而利用了二进制,来构造这样的一种映射关系。不得不说大神就是大神啊。
这到题目是一道很好的练习映射关系的题目。所有以后有映射的题目,尽量使用代码自带的各种机制,不要去自己构造一些别的机制。
还有一种思路就是,直接判断这个header在整个的header中是第几个出现的。
下面是我未完成的代码
#include<cstdio> #include<string> #include<iostream> #include<map> #include<cmath> using namespace std; string line; char A[10]; map<string,char>MAP; //这个函数用于构造0 00 01 等字符串 string creat_map(int i) { string x; } bool initial() { getline(cin,line); for(int i=0;i<line.size();i++) { string x=creat_map(i); MAP[x] = line[i]; } } int readchar() { int x; for(;;) { x=getchar(); if(x=='\n'||x=='\r') continue; return x; } } //用于构造符合读取位数的字符串 string read_string(int n) { memset(A,0,sizeof(A)); for(int i=0;i<n;i++) { A[i]=readchar(); } string str(A); } //用于判断需要读取几位字符 int read_num(int n) { memset(A,0,sizeof(A)); for(int i=0;i<n;i++) { A[i]=getchar(); } int sum=0; for(int i=0;i<n;i++) { if(A[i]=='1') { sum=sum+(int)pow((double)2,n-i-1); } } return sum; } bool is_all_1(string x) { for(int i=0;i<x.size();i++) { if(x[i]!='1')//有一个不是‘1’,说明不是全1 return false; } return true; } void decode() { for(;;) { int num = read_num(3); if(num==7) { printf("\n"); return; } for(;;) { string x = read_string(num); if(is_all_1(x)) break; else printf("%c",MAP[x]); } } } int main() { while(initial()) { decode();//开始解码 } return 0; }
代码的整体结构还是很清晰的,只是低估了部分函数实现的难度。
下面的代码是我模仿汝佳大神的思路写的
//使用汝佳大神的思路来解决这道题目。 #include<cstdio> #include<vector> #include<string> #include<iostream> using namespace std; char map[8][1<<7]; //vector<char> Vector[7];//从001到110一共有七种不同的模块,可以分别对应vector的[1]~vector[6] //如果一个地方必须使用getchar(),那么别的地方也必须使用getchar //getline()也要少用,因为如果从半路开始getline()的话,结果是什么呢? //要不就只使用getline(),不能将getline和别的混合起来。 int readchar() { int x; for(;;) { x=getchar(); if(x=='\n'||x=='\r') continue; return x; } } bool initial() { int x = readchar(); if(x == EOF) return false; //printf("%c",x); map[1][0] = x; for(int len = 2 ;;len++) { for(int pos = 0;pos<(1 << len) - 1;pos++) { x = getchar(); if(x == '\n' || x == '\r') { //printf("\n"); return true; } map[len][pos] = x; //printf("%c",x); } } //printf("\n"); } int read_int(int n) { int sum=0; for(int i=0;i<n;i++) { sum=sum*2+readchar()-'0'; } return sum; } void decode() { for(;;) { int len = read_int(3); //printf("len=%d\n",len); if(len == 0) { printf("\n"); return; } for(;;) { int pos = read_int(len); //printf("pos=%d\n",pos); if(pos==((1<<len)-1)) break; printf("%c",map[len][pos]); } } } int main() { #ifdef local freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif while(initial()) { decode(); } return 0; }
代码结构非常的清晰,从中总结出的几点就是:
1> 关于输入的框架问题,当必须使用getchar()的时候,就全部使用getchar()就好。具体来说,必须使用getchar()的情况是,需要输入的数据存在换行的情况。
当必须使用getline()的时候,就全部使用getline()就可以了,因为我们并不知道从一行的中间来getline(),之后的结果是什么。
2>一般不要使用vector,因为特别是和二维数组进行比较的时候,因为vector的clear还是比较麻烦的。
3>刘汝佳大神的read_int()函数值得好好学习一下。