UVA213

这道题目我先来说一下的我自己的思路:

我自己的思路是,使用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()函数值得好好学习一下。

上一篇:【原创】【中秋直播】自制编程语言 第二章(内附大量干货)


下一篇:L1-039 古风排版