问题描述:
在数据加密和数据压缩中常需要对特殊的字符串进行编码。给定的字母表A由 26 个小写英文字母组成,即$A=\{ a,b,…,z\}$。该字母表所产生的升序字符串是指字符串中字符从左到右出现的次序与字母表中出现的次序相同,且每个字符最多出现 1 次。例如,a、b、ab、bc、xyz 等字符串都是升序字符串。现在对字母表A产生的所有长度不超过 6 的升序字符串按照字典序排列并编码如下:

1 2 26 27 28
a b z ab ac

s对于任意长度不超过 6 的升序字符串,迅速计算它在上述字典中的编码。

#include <iostream>
#include <string>
using namespace std;

double factorial(int n){//递归求阶乘
    if(n==0) return 1;
    if(n==1) return 1;
    else return n*factorial(n-1);
}

double combination(int n,int m){//n下m上
    return factorial(n)/(factorial(m)*factorial(n-m));
}

int index(char c){//字符转索引,a=1...
    return c-'a'+1;
}

int main(){
    string input;
    cin>>input;
    int n=input.length();
    double count=0;
    //先计算前n-1个字符的组合数
    for(int i=1;i<=n-1;i++){
        count+=combination(26,i);
    }
    //再计算加上最高位的组合数
    int prevIndex=0;//最高位字符索引
    for(int i=0;i<n;i++){
        char current=input[i];//当前字符
        int currentIndex=index(current);//当前字符索引
        for(int j=prevIndex+1;j<currentIndex;j++){
            count+=combination(26-j,n-i-1);
        }
        prevIndex=currentIndex;
    }
    //前面算的是前面有几个字符串,因此索引最后要加1
    count++;
    cout<<count;
}