前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++经典算法题-m 元素集合的n 个元素子集

C++经典算法题-m 元素集合的n 个元素子集

作者头像
cwl_java
发布2020-02-13 23:23:39
8680
发布2020-02-13 23:23:39
举报
文章被收录于专栏:cwl_Javacwl_Java

30.Algorithm Gossip: m 元素集合的n 个元素子集

说明

假设有个集合拥有m个元素,任意的从集合中取出n个元素,则这n个元素所形成的可能子集有那些?

解法

假设有5个元素的集点,取出3个元素的可能子集如下:

代码语言:javascript
复制
{1 2 3}、{1 2 4 }、{1 2 5}、{1 3 4}、{1 3 5}、{1 4 5}、{2 3 4}、{2 3 5}、{2 4 5}、
{3 4 5}

这些子集已经使用字典顺序排列,如此才可以观察出一些规则: 如果最右一个元素小于m,则如同码表一样的不断加1

如果右边一位已至最大值,则加1的位置往左移 每次加1的位置往左移后,必须重新调整右边的元素为递减顺序 所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置?

在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1, 因为我们要使用阵列,而最右边的索引值为最大 的n-1,在position位置的值若小于m就不断加1,如果大于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会 经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。

代码示例

代码语言:javascript
复制
#include <stdio.h> 
#include <stdlib.h>
#define MAX 20

    int main(void) {
        int set[MAX];
        int m, n, position; int i;

        printf("输入集合个数 m:"); scanf("%d", &m);
        printf("输入取出元素 n:"); scanf("%d", &n);

        for(i = 0; i < n; i++) set[i] = i + 1;

        // 显示第一个集合

        for(i = 0; i < n; i++) printf("%d ", set[i]);
        putchar('\n'); position = n - 1;
        while(1) {
            if(set[n-1] == m) position--;
            else
                position = n - 1;

            set[position]++;

            // 调整右边元素
            for(i = position + 1; i < n; i++) set[i] = set[i-1] + 1;

            for(i = 0; i < n; i++) printf("%d ", set[i]);
            putchar('\n');

            if(set[0] >= m - n + 1) break;
        }

        return 0;
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-01-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 30.Algorithm Gossip: m 元素集合的n 个元素子集
    • 说明
      • 解法
        • 代码示例
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档