知识储备

1.排列

排列的定义:从n个不同元素中,任取m(m≤n,m与n均为自然数,下同)个元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列;从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,用符号 A(n,m)表示

计算公式:

注意:m中取n个数,按照一定顺序排列出来,排列是有顺序的,就算已经出现过一次的几个数。只要顺序不同,就能得出一个排列的组合,例如1,2,3和1,3,2是两个组合。

2.组合

组合的定义:从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。用符号 C(n,m) 表示。

计算公式:

注意:m中取n个数,将他们组合在一起,并且顺序不用管,1,2,3和1,3,2其实是一个组合。只要组合里面数不同即可

组合算法

0-1转换组合算法摘自:http://blog.chinaunix.net/uid-20684578-id-1572099.html

本算法的思路是开两个数组,一个index[n]数组,其下标0~n-1表示1到n个数,1代表的数被选中,为0则没选中。value[n]数组表示组合的数值,作为输出之用。

  • 首先初始化,将index数组前m个元素置1,表示第一个组合为前m个数,后面的置为0。     
  • 然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为 “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。一起得到下一个组合(是一起得出,是一起得出,是一起得出)
  • 重复1、2步骤,当第一个“1”移动到数组的n-m的位置,即m个“1”全部移动到最右端时;即直到无法找到”10”组合,就得到了最后一个组合。

组合的个数为:

例如求5中选3的组合:

1 1 1 0 0 //1,2,3 
1 1 0 1 0 //1,2,4 
1 0 1 1 0 //1,3,4 
0 1 1 1 0 //2,3,4 
1 1 0 0 1 //1,2,5 
1 0 1 0 1 //1,3,5 
0 1 1 0 1 //2,3,5 
1 0 0 1 1 //1,4,5 
0 1 0 1 1 //2,4,5 
0 0 1 1 1 //3,4,5

代码如下:

#include <iostream>
using namespace std;
void Show(int ,int index[],int value[]);
bool judge(int,int ,int index[]);
void change(int ,int ,int index[],int value[]);
int main()
{
    int i,n,m;
    cout<<"请输入元素个数:";
    cin>>n;
    cout<<"请输入选多少元素:";
    cin>>m;
    int index[n]={0},value[n]; //index务必初始化为0,不然无法知道m个数之后里面是真还是假
    for(i=0;i<n;i++)
    {
        value[i]=i+1;//此处是赋初值,以1,2,3,4,5为例,当然任何数字都可以
    }
    change(n,m,index,value);
    return 0;
}

void Show(int n,int index[],int value[])
{
    int i;
    for(i=0;i<n;i++)
    {
        if(index[i])  cout<<value[i]<<" ";
    }
    cout<<endl;
}

bool judge(int n,int m,int index[])
{
    int i;
    for(i=n-1;i>=n-m;i--)
    {
        if(!index[i])  return false;
    }
    return true;
}

void change(int n,int m,int index[],int value[])  //核心算法函数
{
    int i,j,num=0;
    for(i=0;i<m;i++)
    {
        index[i]=1;
    }
    Show(n,index,value); //第一个组合
    num +=1;
    while(!judge(n,m,index))  //只要没使1全部移到右边,就继续循环
    {
        for(i=0;i<n-1;i++)  //注意是n-1,因为i=n-1时,i+1是不存在的
        {
            //找到10,变成01
            if(index[i]==1&&index[i+1]==0)
            {
                index[i]=0;
                index[i+1]=1;
                //将01组合左边的1全部放在数组最左边
                int count=0;
                for(j=0;j<i;j++)
                {
                    if(index[j])
                    {
                        index[j]=0;
                        index[count++]=1;
                    }
                }
                Show(n,index,value);  //输出
                num +=1;
                break;
            }
        }
    }
    cout<<"共有"<<num<<"种"<<endl;
}

排列组合n选m,组合算法——0-1转换算法(巧妙算法)C++实现相关推荐

  1. Algorithm:【Algorithm算法进阶之路】之算法中的数学编程相关习题(时间速度、进制转换、排列组合、条件概率、斐波那契数列)

    Algorithm:[Algorithm算法进阶之路]之算法中的数学编程相关习题(时间速度.进制转换.排列组合.条件概率.斐波那契数列) 目录 时间速度 排列组合 进制转换 条件概率 斐波那契数列 时 ...

  2. (算法)求数组中数字组合(可多值组合)相加最接近目标数的组合(可能多个)

      今天没事,撸一道算法题   题目要求: 给出一个升序排序的可能重复值的数字数组和一个目标值其中目标值大于数组中最小数,求数组中数字组合(可多值组合)相加最接近目标数的组合(可能多个)不考虑空间复杂 ...

  3. 化生政组合能选计算机专业吗,化生政这个组合好不好? 适合哪些人报考

    新高考3+3选科模式中,选科组合多达20种,使得家长和同学们在众多选科组合中挑花了眼.那么,化生政组合好吗? 化生政组合优势 1.化学与生物学科组合可选择专业较多 如果有同学日后想要从事医药类行业.或 ...

  4. MATLAB_排列组合_摸球组合生成

    已知有n个各不相同的球,从中选出m个球(m<=n),列举出所有可能的组合. %% 摸球组合生成 % 设有n个各不相同的球,从中选取m个球,列举出所有组合. function COM = Comb ...

  5. 学计算机要6选3选什么学科,北京高考6选3组合有多少种?选择学科对有哪些影响?...

    北京高考6选3都有哪些组合呢?其实对于新高考我们部分省份还是很陌生的,面对新的变化以及新的政策,我们的学生和家长们其实更应该注意,小编今天为大家整理了关于北京高考6选3组合的相关情况,以及我们在选科的 ...

  6. 化生政组合能选计算机专业吗,选化生政的女生适合什么专业?女生选化生政好吗?...

    选择科目 测一测我能上哪些大学 选择科目 领取你的专属报告 > 选择省份 关闭 请选择科目 确定 v> 众所周知,当下高中物理对应的高校专业相当之多,但由于难度太大,往往使很多人在新高考选 ...

  7. fifo算法模拟_我是怎样学习算法的?(V1.0)

    我相信很多人都是因为找工作才去看数据结构与算法,我自己也是出于这个目的.我自己在学习数据结构和算法上走了很多弯路,原因就是没有系统地的去学习.看了很多书,刷了很多题,浪费了不少时间,所以希望看到这篇文 ...

  8. python所有组合_Python 生成所有组合

    Python 生成所有组合,除了排列,itertools模块还提供了计算集合元素组合的函数.对于组合来说,顺序不重要.对于一个给定的集合,组合的数量远小于排列的数量,对于 P 个元素组成的集合,r元组 ...

  9. 常用组合逻辑电路及MSI组合电路模板的应用——下篇

    一.加法器 计算机诞生的起因便是计算导弹轨道,因此计算是必经之路. 如何实现两个二进制数的相加呢? 在C语言操作符一节中,我们曾经利用与运算和异或运算,加上循环移位,实现了两个二进制数的 相加. 之所 ...

  10. 【组合数学】组合恒等式 ( 变上项求和 1 组合恒等式 | 三种组合恒等式证明方法总结 | 证明变上项求和 1 组合恒等式 )

    文章目录 一.组合恒等式 ( 变上项求和 1 ) 二.组合恒等式证明方法 ( 三种 ) 三.组合恒等式 ( 变上项求和 1 ) 证明 组合恒等式参考博客 : [组合数学]组合恒等式 ( 递推 组合恒等 ...

最新文章

  1. JavaScript继承的多种方式和优缺点
  2. 奶粉运营,跑数据三个模板。
  3. 常考数据结构与算法:两个链表的第一个公共结点
  4. 场景多、变种快、粒度细,网易易盾是如何有效解决这些内容安全难题的?
  5. go语言基础到提高(10)- 包及方法
  6. Spring集成web环境(手动实现)
  7. idea svn查看提交人_svn 常规操作
  8. Sentinel(十一)之黑白名单控制
  9. MVC web api 返回JSON的几种方式,Newtonsoft.Json序列化日期时间去T的几种方式
  10. Redis系列教程(九):Redis的内存回收原理,及内存过期淘汰策略详解
  11. ESP32烧录bin,乐鑫下载工具使用flash_download_tool
  12. 【深度学习之美】激活引入非线性,池化预防过拟合(入门系列之十二)
  13. (传播智客)刘意Java基础班精华版
  14. 清华学姐教你如何用python处理excel数据
  15. Centos7 镜像下载地址
  16. 从键盘上键入1~7的数字,输出对应星期以及英文缩写
  17. Python:正则表达式 re.sub()替换功能
  18. java无法读取方案文档_解决Spring的java项目打包后执行出现“无法读取方案文档...“、“原因为 1) 无法找到文档; 2) 无法读取文档; 3) 文档的根元素不是...”问题...
  19. 利用上虚拟化,说一下TLB,以及VHE
  20. 用我这些年的经历告诉你无力吐槽的自动化现状……

热门文章

  1. Android的兼容包简介
  2. ESP32的flash_download_tool工具使用问题记录
  3. 数字资产推广面临的问题
  4. OSS 操作权限控制
  5. 计算机右下角日期不能调整,电脑右下角时间不更新_电脑时间不能自动更新
  6. IIS突然启动不了,居然是Web迅雷倒的鬼!
  7. TaskExecutor
  8. 自己动手写推箱子游戏——休闲放松(源码)
  9. python 绘制对数坐标散点图
  10. 为什么要制定和采用计算机图形标准,计算机图形考学试简答题2含答案.doc