问题源于我要对4个数进行排列,自己用了笨拙的穷举算法一个4重循环也得到结果,其中对有相同字母的做排序加删除相邻相等元素的处理。可是如果对100个数进行排列难道用100重循环,后来发现C++11有现成的permute算法,只要一个排序sort()加一个do-while循环就能轻松实现。permute算法有两个next_permutation (vector.begin(), vector.end()); prev_permutation (vector.begin(), vector.end()); 具体的用法以及区别,见下列源代码:

穷举算法代码:

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>using namespace std;void initVect(vector<string>&);
void changeVect(string&);
void permuteVect(vector<string>&,vector<string>&);int main(void)
{vector<string> t4,t3;permuteVect(t4,t3);cout<<"四个不同字母的排列:"<<endl;for (auto v:t4) cout<<v<<" "; cout<<endl<<endl;cout<<"四个字母其中2个相同的排列:"<<endl;for (auto v:t3) cout<<v<<" "; cout<<endl;return 0;
}void initVect(vector<string> &s)
{string n[4]={"A","B","C","D"};s.clear();for (int a=0;a<4;a++)for (int b=0;b<4;b++)for (int c=0;c<4;c++)for (int d=0;d<4;d++)if (a!=b&&a!=c&&a!=d&&b!=c&&b!=d&&c!=d)s.push_back(n[a]+n[b]+n[c]+n[d]);
}void changeVect(string &s)
{for (int i=0;i<4;i++)if (s[i]=='D') s[i]='A';
}void permuteVect(vector<string>&t4,vector<string>&t3)
{initVect(t4);t3=t4;for_each(t3.begin(),t3.end(),changeVect);sort(t3.begin(),t3.end());for (auto it=t3.begin();it!=t3.end();it++)if (*it==*(it+1)) t3.erase(it--);
}/*
执行结果:
四个不同字母的排列:
ABCD ABDC ACBD ACDB ADBC ADCB BACD BADC BCAD BCDA BDAC BDCA CABD CADB CBAD CBDA
CDAB CDBA DABC DACB DBAC DBCA DCAB DCBA四个字母其中2个相同的排列:
AABC AACB ABAC ABCA ACAB ACBA BAAC BACA BCAA CAAB CABA CBAA--------------------------------
Process exited after 1.003 seconds with return value 0
请按任意键继续. . .
*/

permutation算法代码:

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>using namespace std;int main(void)
{vector<string> n1={"C","D","A","B"}; //不按顺序可以测试sort()的必要性 vector<string> n2={"A","A","B","C"};vector<string> t4,t3;sort(n1.begin(),n1.end()); //next_permutation要升序排列,否则会漏算 do t4.push_back(n1[0]+n1[1]+n1[2]+n1[3]);while(next_permutation(n1.begin(),n1.end()));sort(n2.begin(),n2.end());reverse(n2.begin(),n2.end()); //prev_permutation要降序排列do t3.push_back(n2[0]+n2[1]+n2[2]+n2[3]);while(prev_permutation(n2.begin(),n2.end())); cout<<"四个不同字母的排列:"<<endl;for (auto v:t4) cout<<v<<" "; cout<<endl;cout<<endl<<endl<<"四个字母其中2个相同的排列:"<<endl;for (auto v:t3) cout<<v<<" "; cout<<endl;return 0;
}/*
四个不同字母的排列:
ABCD ABDC ACBD ACDB ADBC ADCB BACD BADC BCAD BCDA BDAC BDCA CABD CADB CBAD CBDA
CDAB CDBA DABC DACB DBAC DBCA DCAB DCBA四个字母其中2个相同的排列:
CBAA CABA CAAB BCAA BACA BAAC ACBA ACAB ABCA ABAC AACB AABC--------------------------------
Process exited after 0.9859 seconds with return value 0
请按任意键继续. . .
*/

注:对数组进行排列的写法: int Array[lenth]={...,...}; next_permutation(Array, Array+lenth);

算法的简单应用:

题目:数字0,1,2,3有多少种排列,可以组成多少个不同的四位数?

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>using namespace std;int main(void)
{int y=1,r=0123,h=0;vector<int> m,n={0,1,2,3};//已升序排序略;第1组排列0123不能组成四位数,略;也是设y=1,r=0123的用意for (y;next_permutation(n.begin(),n.end());y++){r=1000*n.at(0)+100*n.at(1)+10*n.at(2)+n.at(3);if (r>1000)  m.push_back(r),h++;}cout<<"0,1,2,3共有"<<y<<"种排列,能组成"<<h<<"个不同的四位数,如下:"<<endl;for (auto n:m) cout<<n<<" ";return 0;
}/*运行结果:0,1,2,3共有24种排列,能组成18个不同的四位数,排列如下:
1023 1032 1203 1230 1302 1320 2013 2031 2103 2130 2301 2310 3012 3021 3102 3120
3201 3210
--------------------------------
Process exited after 0.9471 seconds with return value 0
请按任意键继续. . .
*/

 温馨提示:
  next_permutation()用while-do或for循环会漏第1组排列,建议使用do-while循环

改进一下代码,增加一个临时容器来存放所有的排列,然后在临时容器中读取所有四位数:

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>using namespace std;int vect2number(vector<int> vect)
{int i=0,j=1000;for (auto v:vect) i+=v*j,j/=10;return i;
}int main(void)
{int y=0,r=0;vector<int> m,n={3,2,1,0};sort(n.begin(),n.end());do m.push_back(vect2number(n));while(next_permutation(n.begin(),n.end()));for (auto n:m) {y++; if (n>1000) r++;} //注:此n非彼n,循环体变量与循环体外的变量无关cout<<"0,1,2,3共有"<<y<<"组排列,能组成"<<r<<"个不同的四位数,排列如下:"<<endl;for (auto n:m) if (n>1000) cout<<n<<" "; cout<<endl;return 0;
}/*
注: do m.push_back(vect2number(n));while(next_permutation(n.begin(),n.end()));
可用以下2行代替: m.push_back(vect2number(n));for (;next_permutation(n.begin(),n.end());) m.push_back(vect2number(n));运行结果:0,1,2,3共有24组排列,能组成18个不同的四位数,排列如下:
1023 1032 1203 1230 1302 1320 2013 2031 2103 2130 2301 2310 3012 3021 3102 3120
3201 3210--------------------------------
Process exited after 0.4442 seconds with return value 0
请按任意键继续. . .
*/

附录:

next_permution基本算法思想

1.首先从最尾端开始往前寻找两个相邻元素,令第一元素为*i,第二元素为*ii,且满足*i<*ii。
2.找到这样一组相邻元素后,再从最尾端开始往前检验,找出第一个大于*i的元素,令为*j,将i,j元素对调(swap)。
3.再将ii之后的所有元素颠倒(reverse)排序。

举个实例,假设有序列{0,1,2,3,4},下图便是套用上述演算法则,一步一步获得“下一个”排列组合。图中只框出那符合“一元素为*i,第二元素为*ii,且满足*i<*ii ”的相邻两元素,至于寻找适当的j、对调、逆转等操作并未显示出。

vector 相关文章:

C++ vector声明和赋值的相关函数

C++ vector容器的多种遍历方式

C++ vector 删除和排序的相关函数

C++ vector 赋值、删除、排序类之外的其他函数

C++ vector 容器的全排列算法 next_permutation

C++ vector 容器的全排列算法 next_permutation相关推荐

  1. vector容器与find算法

    from: http://blog.csdn.net/huangyimin/article/details/6133650 好多东西学了过段时间就忘,忘了再搜索再学.也许人一生忘记是硬道理,学习也是硬 ...

  2. 7-5 排列的字典序问题 (10 分)(思路加详解全排列问题+vector容器做法)Come Baby!

    一:题目 n个元素 {1,2, -,n} 有n!个不同的排列.将这 n! 个排列按字典序排列, 并编号为 0,1,-,n!-1 .每个排列的编号为其字典序值.例如,当n=3时,6个不同排列的字典序值如 ...

  3. [通用技术]在不同语言中用协程实现全排列算法(C++/Lua/Python/C#)

    我这里实现全排列的基本算法如下(C++): 1 #include <algorithm> 2 #include <iostream> 3 #include <vector ...

  4. 蓝桥杯——Java中的全排列算法

    蓝桥杯--Java中的全排列 全排列的概念 排列 从n个数中选取m(m<=n)个数按照一定的顺序进行排成一个列,叫作从n个元素中取m个元素的一个排列.不同的顺序是一个不同的排列.从n个元素中取m ...

  5. 实现全排列算法(C++)

    要求:输入任意长度的不含重复元素的数组,打印出该数组的全部全排列. 方向:考虑使用递归算法 1.问题可拆成子问题:将n个元素的全排列拆成n-1个元素的全排列. 2.边界条件(递归的尽头):只有1个元素 ...

  6. vector 容器 动态数组总结

    vector 容器 动态数组总结 二话不说直接上代码 #include <vector> #include <algorithm> #include <iostream& ...

  7. vector容器的用法

    转自一篇博客^-^: 1 基本操作 (1)头文件#include<vector>. (2)创建vector对象,vector<int> vec; (3)尾部插入数字:vec.p ...

  8. 【转】全排列算法非递归实现和递归实现

    来源:http://blog.csdn.net/e3399/article/details/7543861 (一)递归的全排列算法 (A.B.C.D)的全排列为 1.A后面跟(B.C.D)的全排列 2 ...

  9. STL vector 容器介绍

    介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

最新文章

  1. 安装vsftpd-3.0.2.tar.gz源码
  2. java处理oom_java处理OOM和SOF
  3. 数据中台到底包括什么内容?一文详解架构设计与组成
  4. PMCAFF | 刷微信朋友圈行为分析:刷朋友圈是一种感觉?有一种批皇帝批奏章的感觉...
  5. Tjamie 谭传奇来报到
  6. jsDate对象和倒计时图片案例
  7. EDA鸿蒙是不是,如果华为不强研鸿蒙,和阿里合作,新系统或早用到手机上了? - 区块网...
  8. tar.gz 和 tar.bz2 详细解释
  9. android四大组件之Activity以及常见的view处理
  10. bootstrap jasny fileinput插件冲突问题解决
  11. 计算机二级怎么让试题变简单,如何有效利用历年真题备考全国计算机等级考试?...
  12. 适合Java初学者练手的网站
  13. STM32实战总结:HAL之数码管
  14. 【PS】证件照修改尺寸
  15. 【寻址方式】基地址与偏移地址的详细解释
  16. Selenium获取浏览器Network数据包
  17. PHP 中的 use function是什么意思
  18. 营养学和计算机交叉,营养配餐系统综述
  19. 使用国外著名大学数字图书馆资源方法
  20. Bootstrap typeahead自动补全插件的坑

热门文章

  1. 全志Tina Linux Camera 摄像头模块开发指南 全网最详细版本支持百问网T113-Pro DongshanPI-NezhaD1-H DongshanPI-D1s V853-Pro等开发板
  2. 小班中班,随机10以内减法练习题,A4纸可直接打印
  3. 计算机专业课考试分析,计算机考研专业课考试知识点分析
  4. GAN生成对抗网络合集(三):InfoGAN和ACGAN-指定类别生成模拟样本的GAN(附代码)
  5. IDEA配置Cplex
  6. DORIS单节点部署
  7. ELK之ElasticsearchKibana安装/学习
  8. Common Vector Operators(常见的向量操作)
  9. 商女不知亡国恨,隔江犹吃炒腰花
  10. 如何判断一个立即数是否合法