字符典

字符典

在数据压缩和数据加密过程中常需要对特殊的字符串进行编码. 给定的字母表A由26

个小写英文字母组成A?={a,b,...z}. 该字母表产生的升序字符串指的是字符串中字母按

照从左到右出现的次序与字母表中出现的次序相同,且每个字符最多出现1次. 例如,

a,b,ab,xyz,ax等都是升序字符串. 现在对字母表A产生的所有长度不超过6的升序字符串

按照字典序排列如下.
1 2 3 … 26 27 28 …
a b c … z ab ac …
对于给定长度不超过6的升序字符串,编程计算出它在上述字典中的编码.
输入描述
输入数据的第1行是一个正整数k,表示接下来共有k行.在接下来的k行中,每行给出一个

字符串.

输出描述
输出结果,每行对应于一个字符串的编码.

输入样例
3
a
b
abc

输出样例
1
2
352

看了别人的才写出来
题目意思挺简单的 写的时候感觉有点儿绕
/*
有两个函数:
f(i, len) 计算以 字母 i 开头,长度为 len 的字符串的编码
g(len) 计算长度为 len 的字符串的编码

对于给定的字符串 ceg 长度为 3 
步骤:
1、 计算长度为 2 的字符串在字典中的编码
2、 对于首字母 c 计算以 a 和 b 开头的 长度为 3 的字符串的编码 
步骤 3、4 是一个循环 
3、 对于字母 e ,就算 比e 小 、长度为 2 的 字符串的编码
4、 对于字母 g ,计算比 g 小,长度为 1 的字符串的编码 
*/


#include <stdio.h>
#include <string.h>
int s[30];
int f(int i, int len){//以i开头的len长度的
    int sum = 0;
    if(len == 1) return 1;
    for(int j = i + 1; j <= 26; j++){
        sum += f(j, len-1);
    } 
    return sum;
}

int g(int len){
    int sum = 0;
    // 长度为 len 的升序字符串
    for(int i = 1; i <= 26; i++){
        sum += f(i, len);
    } 
    return sum;
}

int calculate(char* str){
    int sum = 0;
    int len = strlen(str);
    memset(s, 0, sizeof s);
    for(int i = 1; i < len; i++){
        sum += g(i);
    }
    
    int x = str[0] - 'a' + 1;  //第一个字符
    //要找到比第一个字符小的  然后还是 len 长度的
    for(int i = 1; i < x; i++){
        sum += f(i, len);
    } 
    
    for(int i = 1; i < len; i++){
        int L = len - i;  //剩下的长度
        int d = str[i] - 'a' + 1;
        int re = str[i-1] - 'a' + 1; //因为要升序   不能比这个小 
        for(int j = re+1; j < d; j++){
            sum += f(j, L);
        }
    }
    return sum+1; 
}
int main(){
    int t;
    char str[10];
    scanf("%d", &t);
    while(t--){
        scanf("%s", str);
        printf("%d
", calculate(str));
    }
    return 0;
}