首页 > 编程语言 > 详细

算法 字典序

时间:2021-04-28 19:07:24      阅读:19      评论:0      收藏:0      [点我收藏+]

问题描述

在数据加密和数据压缩中长需要对特殊的字符串进行编码。给定的字母表由26个小写英文字母组成,即A={a,b,c,…,z}。该字母表产生的升序字符串是指字符串中字母从左到右出现的次序与字母在字母表中出现的次序相同,且每个字母最多出现1次。例如,a、b、ab、bc、xyz等字符串都是升序字符串。现在对字母表A产生的所有长度不超过6的升序字符串按照字典序排列并编码,编码详见教材。 请对于任意长度不超过6的升序字符串,迅速计算出它在字典中的编码。

分析

例如 bcd,我们要先算长度为1和2的所有排序的数量,然后算比第一个字符小的字母即a开头的所有长度为3的排序数量,最后再算他本身的数量。

#include<stdio.h>
#include<string.h>
//得到字符的相对应的数字 
int find(char s){
    return s-a+1;
}
//递归求解一个字母i开头,长度小于k的共有多少个
int singal(int i,int k){
    int num=0;
    if(k==1){
        num=1;
    }
    else{
        for(int j=i+1;j<=26;j++){
            num+=singal(j,k-1);//相当于是第一个字母确定求其他的字母 
        }
    }
    return num;
} 
//把每一个字母开头的长度加起来
int doub(int k){
    int num=0;
    for(int i=1;i<=26;i++){
        num+=singal(i,k);//把所有字母开头的可能性都加起来 
    }
    return num;
} 
//输入一个字符返回一个数字
int getchar(char s[6]){
    int k=strlen(s);
    int sum=0;
    int temp=0;
    temp=find(s[0]);
    //得出k-1之前的所有字符串的个数 
    for(int i=1;i<=k-1;i++){
        sum+=doub(i); 
    }
    //得出小于第一个字母的长度为k的所有组合的个数
    for(int i=1;i<temp;i++){
        sum+=singal(i,k);
    } 
    //以第一个字母作为开始的字符串组合的个数
    for(int i=1;i<=k;i++){
        int t=find(s[i]);
        int len=k-i;
        for(int j=temp+1;j<t;j++){
            sum+=singal(j,len);
        }
        temp=t;
    }
    return sum+1;
}
int main(){
    int n;
    scanf("%d",&n);
    int str[n]={0};
    for(int i=0;i<n;i++){
        char s[6];
        scanf("%s",&s);
        str[i]=getchar(s);
    }
    for(int i=0;i<n;i++){
        printf("%d\n",str[i]);
    }
}

 

算法 字典序

原文:https://www.cnblogs.com/Celiachen/p/14714839.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!