找出字典序
来源:互联网 发布:杀人者的记忆法 知乎 编辑:程序博客网 时间: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
- 找出字典序
- 找出字典中的兄弟单词
- 找出字典中的兄弟单词
- 如何找出字典中的兄弟单词...
- 如何找出字典中的兄弟单词
- 如何找出字典中的兄弟单词
- 如何找出字典中的兄弟单词
- 如何找出字典中的兄弟单词
- 如何找出字典中的兄弟单词
- 如何找出字典中的兄弟单词
- 一个字典,给你一个word找出所有anagram [No. 18]
- 字典序
- 字典序
- 字典序
- 字典序
- 字典序
- 字典序
- 字典序
- HDU's ACM 2152 Fruit
- C#、VB遍历控件并赋值
- 小偷
- 回调函数
- Soot 学习笔记 7:使用 Soot 为应用进行 profiling 插桩
- 找出字典序
- 选择结构和循环结构
- oracle 查询开始和结束日期之间的数据(闭区间)
- 消除视频抖动
- webservice使用中JSON与Java互转工具类
- string、wstring、cstring、 char、 tchar、int、dword转换方法
- hibernate不能创建新的表
- 关于php中解析json时值中包含双引号的问题
- c++视频教程,讲得挺好