求集合的子集
2015-07-07 20:34
204 查看
#include "iostream" using namespace std; /* 功能:求集合的子集 描述:求一个集合的所有子集,如集合{1,2,3},则它的子集为 {},{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3}。 解决:集合的所有子集的个数为2^n,时间复杂度为2^n,空间复杂度做到n, 用二进制来表示子集。此算法为优解,不重复一个也不漏掉一个。 详细:比如有集合{1,2,3},则子集对应的二进制为:000, 100,010,110,001,101,011,111。 取出位为1对应的数:000-->{}, 100-->{1}, 010-->{2}, 110-->{1,2}, 001-->{3}, 101-->{1,3}, 011-->{2,3}, 111-->{1,2,3}。 缺陷:从000到111我们用位移<<的方式来表示,但若这个集合很大,超过64了就不能用位移了, 这样的话我们就自定义的一个跟集合一样大的数组,值为0或者1,来模拟二进制。 扩展:求所有子集元素的和为SUM的子集。 优化:模拟“<<”操作符的MoveToNext函数待以后优化。 版本:VS1.0 Create By Duz on 2015.7.7 */ /* 集合大小200 */ #define NUM 200 /* 子集元素和为10的子集 */ #define SUM 10 /* 需要的子集个数 */ #define GATHER_NUM 5 //数据入口 void init(int *a); void init(int *a, char *filename){} //判断是否为最后一个子集 bool isEnd(int *a); //模拟位移<<1,这个算法唯一可优化的地方就在于这个函数,留后续空余时间优化。 void MoveToNext(int *a); void print(int *a); int main(int argc, char **argv) { int a[NUM] = {0}; //集合 int index[NUM] = {0}; //集合对应的位 int sum = 0; //子集的和 int resultNum = 0; //得到的子集的个数 //读入集合数据 init(a); while (1){ sum = 0; //移位 MoveToNext(index); //得到子集的和 for (int i = 0; i < NUM; i++){ if (index[i]){ sum += a[i]; } } //如果子集和为所需,则输出结果。 if (SUM == sum){ resultNum++; for (int i = 0; i < NUM; i++){ if (index[i]){ cout << a[i] << " ,"; } } cout << endl; } //得到了所需的子集个数,退出 if (GATHER_NUM == resultNum){ break; } //所有的子集都取完了 if (isEnd(index)){ break; } } system("pause"); return 0; } void MoveToNext(int *a) { for (int i = 0; i < NUM; i++){ if (0 == *(a + i)){ //1,找到第一个为0的位 //2,将第一个为0的为置为1 *(a + i) = 1; //3,之前的位全部置为0 memset(a, 0x00, i * sizeof(int)); break; } } } bool isEnd(int *a) { for (int i = 0; i < NUM; i++){ if (0 == *(a + i)){ return false; } } return true; } void init(int *a) { for (int i = 0; i < NUM; i++){ *(a + i) = rand() % 10; } } void print(int *a) { for (int i = 0; i < NUM; i++){ cout << *(a + i) << ","; } cout << endl; }
相关文章推荐
- MYSQY数据库类型与Java类型的对比图(收藏使用)
- UIApplication、AppDelegate、委托
- 2015年7月7日
- winsock基础编程
- 用成员运算符重载函数进行复数运算
- 第5章 使用Linux环境变量
- [LeetCode] ZigZag Conversion [9]
- COJ 0557 4013多重部分和问题
- locale 命令
- JAWR【一个java项目的javascript和CSS集成和压缩工具】
- 针对TCP连接异常断开的分析
- leetCode 27.Remove Element (删除元素) 解题思路和方法
- Wildcard Matching
- The Windy's - POJ 3686 KM算法
- 第4章 更多的 bash shell命令 - df、du、sort、grep、zip、tar等
- Binary Search Tree Iterator
- 密码学基础知识(六)Hash函数与消息认证
- 总结eclipse中安装maven插件
- 自己练习写的Procedure,两种方法遍历cursor,代码已验证
- select、poll、epoll之间的区别总结