找出字典序

来源:互联网 发布:杀人者的记忆法 知乎 编辑:程序博客网 时间:2024/06/13 02:24

问题描述:

任给一个字符串,求如果组成这个字符串的字母按字典序排列,这个字符串会在第几个出现。

解法:

//这是写得比较好的C++算法,当然,下面还有一个格式更加整齐的
#include<iostream>#include<string>#include<iterator>#include<cstdlib>using namespace std;int factorial(int n){    if(n==0)        return 1;    elsereturn n==1?1:n*factorial(n-1);}int arrange(string str){    int arr[26];    memset(arr,0,sizeof(arr));    string::iterator iter=str.begin();    for(;iter!=str.end();++iter)        ++arr[*iter-'a'];    int ans=1;    for(int i=0;i<26;++i)    {        ans*=factorial(arr[i]);    }    ans=factorial(str.length())/ans;    return ans;}bool IsFirstFind(string str,char ch){    string::iterator iter=str.begin();    for(;iter!=str.end();++iter)    {        if(*iter==ch)            return false;    }    return true;}int main(){    string str,smallArr;    int order;    cin>>str;    order=1;    string::iterator iter,temp;    iter=str.begin();    for(;iter<str.end()-1;++iter)    {        for(temp=iter+1;temp!=str.end();++temp){    if(*temp<*iter&&IsFirstFind(smallArr,*temp))    {                smallArr.append(temp,temp+1);string s(iter,temp);s.append(temp+1,str.end());order+=arrange(s);    }        }        smallArr.clear();    }    cout<<order<<endl;    system("pause");    return 0;}



//这是格式更加整齐的,这是以牺牲一定的简洁性换来的,但读起来更方便

#include<iostream>#include<string>#include<iterator>#include<cstdlib>using namespace std;int factorial(int n){    if(n==0)        return 1;    elsereturn n==1?1:n*factorial(n-1);}int arrange(string::iterator beg,string::itetator end){    int arr[26];    memset(arr,0,sizeof(arr));    string::iterator iter;    for(iter=beg;iter!=end;++iter)        ++arr[*iter-'a'];    int ans=1;    for(int i=0;i<26;++i)    {        ans*=factorial(arr[i]);    }    ans=factorial(beg-end)/ans;    return ans;}bool IsFirstFind(string::iterator beg,string::iterator end,char ch){    string::iterator iter;    for(iter=beg;iter!=end;++iter)    {        if(*iter==ch)            return false;    }    return true;}int main(){    string str,smallArr;    int order;    cin>>str;    order=1;    string::iterator iter,temp;    iter=str.begin();    for(;iter<str.end()-1;++iter)    {        for(temp=iter+1;temp!=str.end();++temp){    if(*temp<*iter&&IsFirstFind(smallArr.beg(),smallArr.end(),*temp))    {                smallArr.append(temp,temp+1);string s(iter,temp);s.append(temp+1,str.end());order+=arrange(s.begin(),s.end());    }        }        smallArr.clear();    }    cout<<order<<endl;    system("pause");    return 0;}

//尽管上面的程序已经比较理想了,我还写了个更加完美的

//利用set和map,将程序进行了究极化简

//代码如下

#include<iostream>#include<string>#include<iterator>#include<set>#include<map>#include<cstdlib>using namespace std;int factorial(int n){if(n==0)return 1;elsereturn n==1?1:n*factorial(n-1);}int arrange(string::iterator beg,string::iterator end){map<char,int> alpha_count;string::iterator iter;for(iter=beg;iter!=end;++iter){pair<map<char,int>::iterator,bool> ret=alpha_count.insert(make_pair(*iter,1));if(!ret.second){++ret.first->second; }}int ans=1;map<char,int>::iterator it=alpha_count.begin();for(;it!=alpha_count.end();++it)ans*=factorial(it->second);ans=factorial(end-beg)/ans;return ans;}int main(){string str;int order;set<char> smallerAlpha;cin>>str;order=1;string::iterator iter,temp;iter=str.begin();for(;iter<str.end()-1;++iter){smallerAlpha.clear();for(temp=iter+1;temp!=str.end();++temp){if(*temp<*iter){int ret=smallerAlpha.count(*temp);if(!ret){smallerAlpha.insert(*temp);string s(iter,temp);s.append(temp+1,str.end());order+=arrange(s.begin(),s.end());}}}}cout<<order<<endl;system("pause");return 0;}



//上面的代码set起到了简化的作用,而map则是没什么用的,反而是程序更加麻烦了

//这里使用map完全是为了巩固我对map的掌握,完全可以不用

//综合各种因素,以下是这个程序的最终版

#include<iostream>#include<string>#include<iterator>#include<set>#include<map>#include<cstdlib>using namespace std;int factorial(int n){if(n==0)return 1;elsereturn n==1?1:n*factorial(n-1);}int arrange(string::iterator beg,string::iterator end){int arr[26]; memset(arr,0,sizeof(arr));string::iterator iter; for(iter=beg;iter!=end;++iter)++arr[*iter-'a'];int ans=1;for(int i=0;i<26;++i){ans*=factorial(arr[i]);}ans=factorial(end-beg)/ans;return ans;}int main(){string str;int order;set<char> smallerAlpha;cin>>str;order=1;string::iterator iter,temp;iter=str.begin();for(;iter<str.end()-1;++iter){smallerAlpha.clear();for(temp=iter+1;temp!=str.end();++temp){if(*temp<*iter){<span style="white-space:pre"></span>int ret=smallerAlpha.count(*temp);<span style="white-space:pre"></span>if(!ret)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>smallerAlpha.insert(*temp);<span style="white-space:pre"></span>string s(iter,temp);<span style="white-space:pre"></span>s.append(temp+1,str.end());<span style="white-space:pre"></span>order+=arrange(s.begin(),s.end());<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}}cout<<order<<endl;system("pause");return 0;}

//当然,第三个算法最好,第三个算法是通用的。但第四个是针对这道题目的优化

//对本题来讲,第四个最好

0 0
原创粉丝点击