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

C++经典算法题-产生可能的集合

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

29.Algorithm Gossip: 产生可能的集合

说明

给定一组数字或符号,产生所有可能的集合(包括空集合), 例如给定1 2 3,则可能的集合为:

代码语言:javascript
复制
{}、{1}、{1,2}、{1,2,3}、{1,3}、{2}、{2,3}、{3}。

解法

如果不考虑字典顺序,则有个简单的方法可以产生所有的集合,思考二进位数字加法,并注意1出现的位置,如果每个位置都对应一个数字,则由1所对应的数字所产生的就是一个集合,例如:

在这里插入图片描述
在这里插入图片描述

了解这个方法之后,剩下的就是如何产生二进位数?有许多方法可以使用,您可以使用unsigned 型别加上&位元运算来产生,这边则是使用阵列搜 寻,首先阵列内容全为0,找第一个1,在还没找到之前将走访过的内容变为0,而第一个找到的0则变为 1,如此重复直到所有的阵列元素都变为1为止,例如:

代码语言:javascript
复制
000 => 100 => 010 => 110 => 001 => 101 => 011 => 111

如果要产生字典顺序,例如若有4个元素,则:

代码语言:javascript
复制
{} => {1} => {1,2} => {1,2,3} => {1,2,3,4} =>
{1,2,4} =>
{1,3} => {1,3,4} =>
{1,4} =>
{2} => {2,3} => {2,3,4} =>
{2,4} =>
{3} => {3,4} =>

{4}

简单的说,如果有n个元素要产生可能的集合,当依序产生集合时,如果最后一个元素是n,而倒数第二个元素是m的话,例如:

代码语言:javascript
复制
{a b c d e n}

则下一个集合就是{a b c d e+1},再依序加入后续的元素。

例如有四个元素,而当产生{1 2 3 4}集合时,则下一个集合就是{1 2 3+1},也就是{1 2 4},由于最后一个元素还是4,所以下一个集合就是{1 2+1},也就是{1 3},接下来再加入后续元素4,也就是{1 3 4},由于又遇到元素4,所以下一个集合是{1 3+1},也就是{1 4}。

代码示例

C无字典顺序

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

#define MAXSIZE 20

    int main(void) {
        char digit[MAXSIZE]; int i, j;
        int n;

        printf("输入集合个数:"); scanf("%d", &n);

        for(i = 0; i < n; i++) digit[i] = '0';

        printf("\n{}"); // 空集合

        while(1) {
            // 找第一个0,并将找到前所经过的元素变为0 for(i = 0; i < n && digit[i] == '1'; digit[i] = '0', i++);

            if(i == n)	// 找不到0 break;
            else	// 将第一个找到的0变为1

            digit[i] = '1';

            // 找第一个1,并记录对应位置
            for(i = 0; i < n && digit[i] == '0'; i++); printf("\n{%d", i+1);
            for(j = i + 1; j < n; j++) if(digit[j] == '1')
                printf(",%d", j + 1);

            printf("}");
        }

        printf("\n");

        return 0;
    }

C字典顺序

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

#define MAXSIZE 20

    int main(void) {
        int set[MAXSIZE]; int i, n, position = 0;

        printf("输入集合个数:"); scanf("%d", &n);
        printf("\n{}"); set[position] = 1;

        while(1) {
            printf("\n{%d", set[0]);	// 印第一个数
            for(i = 1; i <= position; i++) printf(",%d", set[i]);
            printf("}");

            if(set[position] < n) { // 递增集合个数set[position+1] = set[position] + 1; position++;
            }
            else if(position != 0) {	// 如果不是第一个位置
                position--;	// 倒退
                set[position]++;	// 下一个集合尾数
            }
            else	// 已倒退至第一个位置
                break;
        }

        printf("\n");

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 29.Algorithm Gossip: 产生可能的集合
    • 说明
      • 解法
        • 代码示例
          • C无字典顺序
          • C字典顺序
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档