求集合的子集是算法中比较典型的一个例子,它的几种解法比较能体现算法的一些思路,
网上也有一些思路,但都比较零散,我希望做一个总结,完善起来,方便参考。
重点还是关注,算法的思想,解决问题的思路。
第一种:位图法
思路:
通过组合排列来遍历所有可能的子集。
set={a, b ,c}
可以用一组二进制序列来表示集合的非空子集:
001
010
011
100
101
110
111
相应的位如果是1 则打印相应的元素,就得到全部非空子集。
-
# include <stdio.h>
-
-
# define MAX_NUM 50
-
# define STR_NUM 20
-
-
int main()
-
{
-
char set[MAX_NUM] = "0123456789abcdefghij";
-
const int max_set_num = 1 << STR_NUM;
-
int i, j, k;
-
for (i = 0; i < max_set_num; i++) { //遍历所有可能的组合,数值从1到2的7次方减1
-
for (j = 0, k = i; j < STR_NUM; j++) { //对于每一个组合,判断二进制位,打印
-
if (k & 1) {
-
printf("%c ", set[j]);
-
}
-
k = k >> 1;
-
}
-
printf("\n"); //得到一个非空集合
-
}
-
return 0;
-
}
注:如果 i值初始化为 0,会打赢一个空行,可表示空集,这样就能得到集合的所有子集,相当于增加了二进制全零序列。
---------------------------------------------------------------------------
性能:
当字符数组长度达到20个字符时:
real 0m16.842s
user 0m1.111s
sys 0m1.458s
---------------------------------------------------------------------------
阅读(2674) | 评论(0) | 转发(0) |