牛客网竞赛题(密码转译)

牛客网竞赛题(密码翻译)

现在定义一种编码规则:对于长度为3的字符串(均由小写字母组成),首先按照字典序进行排序,即aaa,aab,aac,…,zzz,

将这些字符串按照顺序依次从00001至17575编码(前缀0不可省略),即aaa=00000,aab=00001,aac=00002,…,zzz=17575。

现在给出一串数字,请你通过计算输出这串数字对应的原字符串。(输入保证该数字长度为5的倍数)

例如输入000021757511222,每五位编号对应于一个字符串

编号00002对应字符串 aac

编号17575对应字符串 zzz

编号11222对应字符串 qpq

故输出为 aaczzzqpq

问题的分析:

问题的核心

如何将输入的数字字符串译码为一个目标字符串,观察题目描述,00000 代表aaa,00001代表aab,说明这种命名方式是从第一位字符串开始往后改变,顺序从左至右,可以采取取余来判断,应该改变哪个为位置上的字符

举一个简单的例子

这个就类似于十位数一样,个位从1到9,然后十位进一,个位置0,十位从1到9,然后百位进1,十位置0…

比如说113,

  • 我要得到百位上的数字,那么就是113/100 == 1
  • 得到十位的数字 113%100/10==1
  • 得到个位的数字 113%10 == 3;

那么从这道题出发:

  • 获得第一位数字 p = num/(26*26)

  • 获得第二位数字 p = (num%(26*26))/26

  • 获得第三位数字 p=num%26;

这样三位的数字都可以得到了

代码实现:

            //00001到aab的核心
            //先求第一位
            p = num/(26*26);
            code = code + getCode(p);
            //再求第二位
            p = (num%(26*26))/26;
            code = code + getCode(p);
            //再求最后一位
            p = num%26;
            code = code + getCode(p);

数据组织:

//定义一个结构体用于存储数据,最多能输入100个编码,所以字符串数组也最多能保存100个编码
#include<iostream>
#include<string>
using namespace std;
#define MaxSize 100
//数据组织,存储编译后的数据
typedef struct{
    string data[MaxSize]; //存储最终编码的数组
    int length;//编码的长度
}PostCode;

初始化顺序表

//初始化数据结构
void InitPostCode(PostCode *&Pos){
    //申请存储空间
    Pos = (PostCode*)malloc(sizeof(PostCode));
    Pos->length = 0;
}

添加目标代码

//添加翻译后的密码
bool AddElem(PostCode *&Pos,string code){
    if(Pos->length>=MaxSize) return false;
    Pos->data[Pos->length] = code;
    Pos->length++;
    return true;
}

打印顺序表中的密码

//输出密码
void DispPostCode(PostCode *Pos){
    printf("This code is\n");
    if(Pos->length<=0) return;
    int i = 0;
    for(;i<Pos->length;i++){
        cout<<Pos->data[i]<<endl;
    }
    printf("\n");
}

翻译代码

//对于每一位对应的整数,返回特定整数对应的字母
string getCode(int style){
    switch(style){
        case 0: return "a";
        case 1: return "b";
        case 2: return "c";
        case 3: return "d";
        case 4: return "e";
        case 5: return "f";
        case 6: return "g";
        case 7: return "h";
        case 8: return "i";
        case 9: return "j";
        case 10: return "k";
        case 11: return "l";
        case 12: return "m";
        case 13: return "n";
        case 14: return "o";
        case 15: return "p";
        case 16: return "q";
        case 17: return "r";
        case 18: return "s";
        case 19: return "t";
        case 20: return "u";
        case 21: return "v";
        case 22: return "w";
        case 23: return "x";
        case 24: return "y";
        case 25: return "z";
    }
    return "\0";
}

将00001翻译成三位的小写字母

/**
 * 将字符序列翻译成字母,扫描目标数组,每五个一组,放入一个新的临时数组中
 * 然后对这个数组进行转移翻译,然后将翻译后的到的字符数组放入目标字符串code中
 * 最后将字符数组放入顺序表中,链表也行(采用顺序表存储数据结构)
 * @param a
 * @param len
 * @param Pos
 * @return
 */
bool Translate(char a[],int len,PostCode *&Pos){
    char temp[5];  //定义的用于存储五位字符的密码,因为五位数组字符代表一个三位的目标密码
    int pos = 0; //定义的中间变量
    int num,j,p;
    string code = ""; //最终翻译的目标密码
    for(int i=0;i<len;i++){
        temp[pos] = a[i];
        pos++;
        if((i+1)%5==0){ //temp字符数组已经有了五个字符,开始进行翻译
            pos = 0;
            //编码已满,对其进行编码
            num = 0; 
            for(j=0;j<5;j++){ //将字符00001转化为整数
                if(temp[j]<'0'||temp[j]>'9'){
                    cout<<"I will return\n";
                    return false;
                }
                num = 10*num+(temp[j]-'0');
            }
            //先求第一位
            p = num/(26*26);
            code = code + getCode(p);
            //再求第二位
            p = (num%(26*26))/26;
            code = code + getCode(p);
            //再求最后一位
            p = num%26;
            code = code + getCode(p);
        }
    }
    AddElem(Pos,code); //将目标字符添加到顺序表中
    cout<<"Successfuly translate!\n";
    return true;
}

主函数入口

//主函数入口
int main(){
    int T; //测试用例个数
    int num; //字符串的长度
    PostCode *Pos;
    InitPostCode(Pos);
    printf("Please input this testcase nums:\t");
    scanf("%d",&T);
    printf("\nThis testcase num is %d\n",T);
    if(T<=0||T>10) return -1;
    int temp = T;
    while(T>0){
        printf("please input the %d testcase in the line1 input this nums:",(temp-T+1)); 
        scanf("%d",&num);
        printf("This num is\t%d\n",num);
        if(num%5!=0&&num!=0) return -2;
        char datas[num+1];
        printf("Please input the string:");
        cin.ignore();
        cin.getline(datas,num+1);
        //对字符数组进行转码
        Translate(datas,num,Pos);
        T--;
    }
    DispPostCode(Pos);
    return 0;
}
#测试结果1
please input the 1 testcase in the line1 input this nums:5
This num is    5
Please input the string:10023
Successfuly translate!
This code is
ovn #ovn就是10023经过翻译得到的目标代码
#测试结果2
Please input this testcase nums:3

This testcase num is 3
please input the 1 testcase in the line1 input this nums:15
This num is    15
Please input the string:000230012200123
Successfuly translate!
please input the 2 testcase in the line1 input this nums:10
This num is    10
Please input the string:0001200232
Successfuly translate!
please input the 3 testcase in the line1 input this nums:20
This num is    20
Please input the string:00012000230123401123
Successfuly translate!
This code is
#最终的转译密码
aaxaesaet #对应数字字符000230012200123
aamaiy #对应数字字符0001200232
aamaaxbvmbrf #对应数字字符00012000230123401123

如果还有更简单空间复杂度和时间复杂度以及其它实现方式的小伙伴,可以一起交流呀

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值