排列

全排列是将一组数按一定顺序进行排列,如果这组数有n个,那么全排列数为n!个。现以{1, 2, 3}为例说明如何编写全排列的递归算法

第一层S1表示第一个数分别与第1、2、3个数交换位置,如123是1和第一个数1交换,213是1和第二个数2交换,321是1和第三个数交换

第二层S2是第二个数分别与第2、3个数交换位置。则最后一层的所有叶子节点,即为全排列的所有结果。第k层中的节点Sk就是父节点中的第k个数,分别与第k、k+1...n个数交换位置。

也可用stl的next_permutation()和perv_permutation()

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; template <class T>
class Perm
{
public:
//由于vector本身就是模板,在其模板参数未确定之前,也就是具体类型没有确定之前,这个T是未知的
//typename就是告诉编译器先不管具体类型,等模板实例化的时候再确定
void perm(vector<T> &a,typename vector<T>::iterator begin);
bool is_swap(typename vector<T>::iterator i,typename vector<T>::iterator j);
private:
static int i;
};
template <class T>
int Perm<T>::i=; template <class T>
bool Perm<T>::is_swap(typename vector<T>::iterator i,typename vector<T>::iterator j)
{
for(typename vector<T>::iterator k=i;k!=j;++k)
if(*k==*j)
return false;
return true; } template <class T>
void Perm<T>::perm(vector<T> &a,typename vector<T>::iterator begin)
{
if(begin==a.end())
{
cout<<" 第"<<++i<<" 个排列为:";
for_each(a.begin(),a.end(),[](int i)
{
cout<<i<<" ";
});
cout<<endl;
}
for(auto i=begin;i!=a.end();++i)
{
if(!is_swap(begin,i))
continue;
swap(*begin,*i);
perm(a,begin+);
swap(*begin,*i);
}
} int main()
{
vector<int> a;
int n;
cout<<" 请输入元素的个数:"<<endl;
cin>>n;
for(int i=;i<n;++i)
{
int t;
cin>>t;
a.push_back(t);
} Perm<int> p;
p.perm(a,a.begin());
return ;
}

组合

第一层S1中的节点是数组中的所有数字,第二次S2中的节点是分别从父节点的下一个位置开始。因为这个例子中m=2,所以共有2层。从第一层到第二层,深度遍历这颗树,即可得到所有组合。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; template <class T>
class Combine
{
public:
void combine(vector<T> a,int begin,int num);
private:
vector<T> r;
}; template <class T>
void Combine<T>::combine(vector<T> a,int begin,int num)
{
if(a.empty())
{
cout<<" 要组合的数组为空."<<endl;
return;
}
if(num==)
{
for_each(r.begin(),r.end(),[](T i)
{
cout<<i<<" ";
});
cout<<endl;
     return;
}
for(int i=begin;i<a.size();++i)
{
r.push_back(a.at(i));
combine(a,i+,num-);
r.pop_back();
}
} int main()
{
vector<int> a;
int n;
cout<<" 请输入元素的个数:"<<endl;
cin>>n;
for(int i=;i<n;++i)
{
int t;
cin>>t;
a.push_back(t);
} int num;
cout<<" 请输入要选择的个数:"<<endl;
cin>>num;
Combine<int> c;
c.combine(a,,num);
return ;
}

执行过程:

  第一次for也就是开始:beign=0,i=0,num=2;进入下一次递归也就是第二次for循环,beign=1,i=1,num=1;第三次递归时num==0,输出,本次递归结束。返回到第二次递归也就是第二次for循环,i自增1

  在第二次for循环里面进行递归也就是第四次for循环(有点绕。。。),begin=1,i=2,num=1;第五次for循环时num==0,结束本次递归,退回到第二次for循环;i自增1,结果不符合for循环条件,第二次

  for循环结束;以此推。。。(黑体加粗为同一层for循环)

排列组合算法(基于c++实现)的更多相关文章

  1. 排列组合算法(PHP)

    用php实现的排列组合算法.使用递归算法,效率低,胜在简单易懂.可对付元素不多的情况. //从$input数组中取$m个数的组合算法 function comb($input, $m) { if($m ...

  2. C#语法灵活运用之排列组合算法

    今天群里有朋友求一个排列组合算法,题目是给定长度,输出所有指定字母的组合. 如指定字母a.b.c.d.e.f,长度为2,则结果应为:aa.ab.ac ... ef.ff. 有朋友给出算法,很有特色: ...

  3. python实现高效率的排列组合算法-乾颐堂

    组合算法 本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标 代表的数被选中,为0则没选中. 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数. 然后从左到右扫描数组 ...

  4. 排列组合算法的javascript实现

    命题:从成员数为N的集合S中,选出M个元素,分别求其排列与组合结果集,即 A(N, M)与C(N, M) js解法: function queue(arr, size){ if(size > a ...

  5. c语言中一种典型的排列组合算法

    c语言中的全排列算法和组合数算法在实际问题中应用非常之广,但算法有许许多多,而我个人认为方法不必记太多,最好只记熟一种即可,一招鲜亦可吃遍天 全排列: #include<stdio.h> ...

  6. 针对较大基数的排列组合算法Java实现类(n选m)

    package com.utils; import java.math.BigDecimal; import java.math.RoundingMode; public class PLZUUtil ...

  7. C(n,m)排列组合算法

    主要解决C(n,m)问题 static class Extension { public static IList<IList<T>> GetGroup<T>(th ...

  8. 排列组合算法的Java实现

    转载于:http://cgs1999.iteye.com/blog/2327664

  9. N个数组中所有元素的排列组合(笛卡尔积)算法

    (1)N个数组对象中所有元素排列组合算法 private List<List<Object>> combineAlg(List<Object[]> nArray) ...

随机推荐

  1. 计算机bit是什么意思

    bit是计算机中数据的最小单位,即二进制位,数字0和1 一个字节是八位(8个0和1 或 1 组成的一串二进制) 一个字是16位,等于2个字节 用八位二进制表示的字符叫单字节字符, 用16位二进制数表示 ...

  2. 20145311 《Java程序设计》第2周学习总结

    20145311 <Java程序设计>第2周学习总结 教材学习内容总结 3.1Java的类型分为基本类型(Primitive type)和类类型(Class type)基本类型: *整数: ...

  3. 20162314 Experiment 3 - Sorting and Searching

    Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...

  4. Windows Shell编程之如何编写为文件对象弹出信息框的Shell扩展

    有关COM编程资料 转载:http://www.cnblogs.com/lzjsky/archive/2010/11/22/1884702.html 活动桌面引入一项新特性, 当你在某些特定对象上旋停 ...

  5. 同样的输入,为什么Objects.hash()方法返回的hash值每次不一样?

    背景 开发过程中发现一个问题,项目中用Set保存AopMethod对象用于去重,但是发现即使往set中添加相同内容的对象,每次也能够添加成功. AopMethod类的部分代码如下: public cl ...

  6. codeforces 98 div2 C.History 水题

    C. History time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  7. FreeSouth的学习osg小贴士

    http://www.osgchina.org/index.php?option=com_content&view=article&id=150&catid=91&It ...

  8. linux shell执行原理

    shell简介 Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令并把它送入内核去执行. 运行背景 a 一个基本的linux系统结构 b.由上图可以看出,shel ...

  9. 将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class、缺少 xsd、重复打包依赖)

    最近在看 spring boot 的东西,觉得很方便,很好用.对于一个简单的REST服务,都不要自己部署Tomcat了,直接在 IDE 里 run 一个包含 main 函数的主类就可以了. 但是,转念 ...

  10. UVA-307 Sticks (DFS+剪枝)

    题目大意:用n根长度未必相等的木棒匹配出最多数量的等长木棒. 题目分析:枚举所有可能的等长木棒的长度,通过DFS的方式逐根匹配,在此过程中要剪枝.先将木棒长度按从大到小排序,也就是说匹配每一根等长木棒 ...