字典序問題的解決方案


問題描述:
在數據加密和數據壓縮中常需要對特殊的字符串進行編碼.給定的字母表A由26個小寫英文字母組成,即A={a,b...z}.該字母表產生的長序字符串是指定字符串中字母從左到右出現的次序與字母在字母表中出現的次序相同,且每個字符最多出現1次.例如,a,b,ab,bc,xyz,等字符串是升序字符串.現在對字母表A產生的所有長度不超過6的升序字符串按照字典排列編碼如下:a(1),b(2),c(3).........,z(26),ab(27),ac(28),..................

對於任意長度不超過6的升序字符串,迅速計算出它在上述字典中的編碼.

算法設計:
對於給定的長度不超過6的升序字符串,計算它在上述字典中的編碼.

數據輸入:
輸出數據由文件名為input.txt的文本文件提供.文件的第1行是一個正整數k,表示接下來共有k行,在接下來的k行中,每行給出一個字符串.

結果輸出:
將計算結果輸出到文件output.txt.文件共有k行,文件共有k行,每行對應於一個字符串的編碼.
  輸入文件示例:
    input.txt
   2
   a
   b

輸出文件示例:
output.txt
1
2

 

#include <iostream>
#include<fstream>
using namespace std;
//計算階乘
int factorial(int n)
{
    if (n==0)
    {
        return 1;
    }
    int sum=1;
    for (int i=1;i<=n;i++)
    {
        sum*=i;
    }
    return sum;
}
//統計n位中取p位的情況個數
int getnp(int p,int n)
{
    int sum=1;
    for (int i=n-p+1;i<=n;i++)
    {
        sum*=i;
    }
    return sum/factorial(p);
}
//統計在總位數一樣的情況下第p位前有多少
int getp(char a,int p,int n)
{
    int sum = 0;
    for (int i = n+1;i<(a-'a'+1);i++)
    {
        sum += getnp(p-1,(26-i));
    }
    return sum;
}
void main()
{
    int sum=0;
    int size=0;
    char buffer[20];
    ifstream inputfile("D:\\12.txt.txt");
    ofstream outputfile("1-2out.txt");
    while(!inputfile.eof())
    {
        inputfile.getline(buffer,20);
        sum=0;
        size = strlen(buffer);
        for (int i=1;i<size;i++)
        {
            sum += getnp(i,26);
            sum += getp(buffer[i],size-i,buffer[i-1]-'a'+1);
        }
        sum += getp(buffer[0],size,0);
        sum++;
        outputfile<<sum<<"\n";
    }
    outputfile.close();
}

如上代碼,思想為,例如egh這樣的情況,那我們先把只有一位長的情況和兩位長的加起來,即為26C1和26C2,然后找出起始位為a,b,c,d的三位單詞的情況,它們也排在efg之前,即為25C2,24C2,23C2,22C2(這里需要注意並不是26C2了,因為如果為a開頭,那后面兩位只能從b以后的數開始選,即25個,b開頭的為24個以此類推),然后考慮e開頭的,因為在上面的情況過后就是高位以e開頭的情況,這個時候需要注意,eah,ebh這樣的並不合理,所以我們要將getp(buffer[i],size-i,buffer[i-1]-'a'+1),buffer[i]和buffer[i-1]進行比較即為e和g進行比較然后通過比較只有ef為開頭的才合理,然后我們計算從efa到efz,繼而到最后一位由於ega,egb這種不存在(通過buffer的比較可知),因此沒有其他在eg開頭的情況了,即是egh是eg開頭的三位數的第一種情況,此時我們的定位工作就完畢了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM