一个字符串编码问题的程序解决

原题:
/*
描述
为了最大程度地节约存储空间,经常需要把信息进行编码。一种很有效的编码方法是用数字来表示一串字符。假设这些字符串都是由不重复的英文小写字母组成的,且每个字符串中的英文字母都是从小到大排列的。
这个编码系统按照如下的方式工作:
字符串是按照长度从小到大的顺序排列的
长度相同的字符串,是按照字典需排列的
则根据这个编码系统,所有的字符串从 a 开始可以编码如下:
a - 1 b - 2 … z - 26 ab - 27 … az - 51 bc - 52 … vwxyz - 83681 …

那么,请编程计算出一个字符串在这个编码系统下编码后的值是多少。
输入
输入的第一行为 N,表示有 N 组数据。后面的 N 行每行包含一个不超过 10 个字母的字符串。
输出
输出字符串所对应的编码,如果该字符串不能被编码,则输出 0。
测试用例 1 以文本方式显示
1
bf
以文本方式显示
55

*/

解决代码:

#include<stdio.h>
#include<string.h>
#include <iostream>
#include <math.h>

using namespace std;
long long t[10][26]= {0};    //查表,将最简形式的编码事先准备好 
/*

行号:  0   1    2    3    4   ...   24   25 
列号:0 a    b    c    d    e    ...   y   z  
      1 ab   bc   cd   de   ef   ...   yz  zz
      2 abc  bcd  cde  efg  ghi  ...   xyz zzz
      3
      4
      ...
      9 abcdefghij  .....           qrstuvwxyz ...zzzzz
*/
void init_table()
{
    int i,j;
    for(i=0;i<26;i++)
    {
        t[0][i]=i+1;  //对应的是 a/b/c/.../z的编码是1-26; 
    }

    for(i=1;i<10;i++)
    {
        t[i][0]=t[i-1][25]+1;  //abc 总是等于上一行(降阶) yz  +1 
        for(j=1;j<26-i;j++)
        {
            t[i][j] =  t[i][j-1] + 1 + t[i-1][25] - t[i-1][j];
            //cde - bcd = byz + 1 - bcd = 1 + yz - cd 

        }
        for(j=26-i;j<26;j++)
        {
            t[i][j]=t[i][j-1]; //因为z2、y3这些不合法,所以无增加编码,都是和前面的最简式子一样的数 
        }

    }

    return;
}
long long  lookup(char *sNum)
{
    /*
    举例: 
    bdfxz = b4 - c3 + d3 - e2 + f2 - g1 +x1 - y0 +z0

    */
    long long ret =0;
    int i,j;
    char *p = sNum;
    int n = strlen(p);
    while(n>1)
    {
        i = n-1;
        j = *p - 'a';
        ret = (t[i][j] - t[i-1][j+1]) + ret;
        n--;
        p++;
    }
    ret += t[0][*p-'a'];

    return ret;

}
int main(void)
{
    int i,j,k;
    char s1[80]="vwxyz";
    //Soloe@csdn 欢迎转载,但请保留 
    init_table();

    int n;
    cin>>n;
    while(n>0)
        {
            cin>>s1;
            cout<<lookup(s1)<<endl;
        }

    return 0;
//Soloe@csdn 欢迎转载,但请保留
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值