Chinaunix首页 | 论坛 | 博客
  • 博客访问: 214761
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-09 10:55
个人简介

每天改变一点点,生活充满了惊喜。

文章分类

全部博文(42)

文章存档

2016年(8)

2015年(29)

2014年(5)

我的朋友

分类: C/C++

2014-08-03 13:57:14

求集合的子集是算法中比较典型的一个例子,它的几种解法比较能体现算法的一些思路,
网上也有一些思路,但都比较零散,我希望做一个总结,完善起来,方便参考。
重点还是关注,算法的思想,解决问题的思路。

第一种:位图法

思路:
通过组合排列来遍历所有可能的子集。
set={a, b ,c}
可以用一组二进制序列来表示集合的非空子集:
001
010
011
100
101
110
111
相应的位如果是1 则打印相应的元素,就得到全部非空子集。

  1. # include <stdio.h>

  2. # define MAX_NUM 50
  3. # define STR_NUM 20

  4. int main()
  5. {
  6.     char set[MAX_NUM] = "0123456789abcdefghij";
  7.     const int max_set_num = 1 << STR_NUM;
  8.     int i, j, k;
  9.     for (i = 0; i < max_set_num; i++) { //遍历所有可能的组合,数值从1到2的7次方减1
  10.         for (j = 0, k = i; j < STR_NUM; j++) { //对于每一个组合,判断二进制位,打印
  11.             if (k & 1) {
  12.             printf("%c ", set[j]);
  13.         }
  14.         k = k >> 1;
  15.     }
  16.     printf("\n"); //得到一个非空集合
  17.     }
  18.     return 0;
  19. }
注:如果 i值初始化为 0,会打赢一个空行,可表示空集,这样就能得到集合的所有子集,相当于增加了二进制全零序列。
---------------------------------------------------------------------------
性能:
当字符数组长度达到20个字符时:
real 0m16.842s
user 0m1.111s
sys 0m1.458s
---------------------------------------------------------------------------
阅读(2590) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~