求子集合问题

Profiteerchen 2008-04-11 10:32:46
當你手邊有一數值的集合 S={S1, S2, …, SN},集合內成員為 整數。你想知道在集合 S內是否 存在 任何子集合其內所有數字的加總等於某一數值 K。寫一程式提供使用者輸入集合 S 與待查詢數值 K,並顯示所有滿足條件的子集合。

【程式執行範例說明】

輸入集合所有內容(集合S包含至少6筆資料) Ü 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

輸入待查詢數值 Ü 10

輸出結果 Ü (1, 2, 7) (1, 3, 6) (1, 4, 5) (2, 3, 5)

這個應該怎么寫呀
...全文
413 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
colaNicy 2008-04-12
  • 打赏
  • 举报
回复
可以用贪婪法解
ryfdizuo 2008-04-11
  • 打赏
  • 举报
回复
 	
const int ListLength=10;

//输出Buffer集合
void Output(char *Buffer, int flag)
{
if(flag!=3)
return;
static int count=1;

cout<<count++<<": {";
for(int i=0; i<flag; i++)
{
cout<<Buffer[i];
}
cout<<"}"<<endl;
}

//找到元素c在集合List中的位置
int Index(char *List, char c)
{
for(int i=0; i<=ListLength-1; i++)
{
if(c==List[i])
{
return i;
break;
}
}
return -1;
}

int GetSum(char* dest, int flag)
{
int sum=0, i=0;
while (i<=flag)
sum+=(dest[i++]-'0');

return sum;
}

void SubSet(char *List, int m, char *Buffer, int flag, int dest)
{
if(m <= ListLength-1)
{
for(int i=(flag==0) ? 0 : Index(List,Buffer[flag-1])+1; i<=ListLength-1; i++)
//当flag==0时,Buffer中没有任何元素,此时i=[0...ListLength-1]
//当flag>0时,找到Buffer中的最后一个元素在集合List中的位置i,把[i....ListLength-1]
//处的元素,加到Buffer元素的最后面
{
Buffer[flag]=List[i];
if(GetSum(Buffer, flag)==dest)
Output(Buffer,flag);
SubSet(List, m+1, Buffer,flag+1, dest);
}
}
return;
}

int main()
{
char List[ListLength]={'1','2','3','4','5','6','7','8','9','10'};
char Buffer[ListLength]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};

int U=10;
SubSet(List,0,Buffer,0, U);
system("pause");
return 0;
}
//output:
1: {123}
2: {127}
3: {136}
4: {145}
5: {235}
请按任意键继续. . .
ryfdizuo 2008-04-11
  • 打赏
  • 举报
回复
lz为什么给出的测试数据输出只有:
(1, 2, 7) (1, 3, 6) (1, 4, 5) (2, 3, 5)
难道要求必须有三个元素?
effective_person 2008-04-11
  • 打赏
  • 举报
回复

// 2.cpp : 定义控制台应用程序的入口点。
//
/*
这是我刚刚写写的。
思路是这样的: 先求子集然后 求和。
求和:
假设这个集合有 3个数 a b c那么它就对应一个 3位的2进制数
我们可以把它这些子集分别对应一个二进制数
子集 空集 {c}, {b}, {c,b}, {a}, {a,c}, {a,b},{a,b,c}
对应的2进制数 000, 001, 010, 011, 100, 101, 110, 111
那么10个数也是类似:

这样就可根据一个二进制数取出位为1的元素,作为子集的元素。
在对这些元素求和即可。
*/
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <bitset>
void print(const std::vector<int> & x)//打印
{
for(std::vector<int>::const_iterator cit=x.begin();
cit!=x.end();++cit)
{
std::cout<<*cit<<" ";
}
std::cout<<std::endl;
}
bool sum(const std::vector<int> & v,int k)//求和
{
int total=0;
for(std::vector<int>::const_iterator it=v.begin();
it!=v.end();++it)
{
total+=*it;
}
return total==k;
}

int main()
{
std::vector<int> v;
for(int i=1;i<=10;i++)
v.push_back(i);
unsigned int k;
std::cin>>k;
for(unsigned short j=0;j<pow(double(2),double(v.size()));j++)
{
std::bitset<10> b(j);//从一整形转成 2进制数
std::vector<int> f;//存放 子集
for(int index=0;index!=v.size();index++)//把位为1的元素加入子集中
{
if(b.at(index)==1)
f.push_back(v.at(index));
}
if(!f.empty()&&sum(f,k))//如果子集的和等于k就打印
print(f);
}
return 1;
}
Profiteerchen 2008-04-11
  • 打赏
  • 举报
回复
意思就是求出集合的子集合,要求子集合中的数之和为输入的待查询数值
过客猫2022 2008-04-11
  • 打赏
  • 举报
回复
这里有集合的实现的模板源代码,你可以看看,参考一下
http://blog.csdn.net/zdhsoft/archive/2008/04/08/2261691.aspx
myullian 2008-04-11
  • 打赏
  • 举报
回复
没看懂,集合 S內是否 存在 任何子集合其內所有數字的加總等於某一數值 K?
为什么没有输出(1,2,3,4)?
Supper_Jerry 2008-04-11
  • 打赏
  • 举报
回复
也可以先对集合S排序一下,
拆分待查找数字的时候,先2分查找,然后就把后面的忽略不查了。
Supper_Jerry 2008-04-11
  • 打赏
  • 举报
回复
递归遍历哦
wenjun1130 2008-04-11
  • 打赏
  • 举报
回复
ls 正解
c_spark 2008-04-11
  • 打赏
  • 举报
回复
如果数据量不是很大,那先对数组排序,然后利用回朔就行了,得出所有子集和为k的集合...
大量的数据的时候就必须优化算法了啊...
#include <stdio.h>
#include <stdlib.h>

int value[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int tmp[10];

int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}

void solve(int sum, int k, int num, int s)
{
if(sum == k)
{
printf("(%d",tmp[0]);
for(int i = 1; i<num; ++i)
printf(",%d",tmp[i]);
printf(")\n");
return;
}
for(int i = s; i < 10; ++i)
{
if(sum + value[i] <= k)
{
tmp[num++] = value[i];
solve(sum+value[i],k,num,i+1);
num--;
}
}
}

int main()
{
int k;
k = 10;
qsort(value,10,sizeof(value[0]),cmp);
solve(0,k,0,0);
return 0;
}


输出:
(1,2,3,4)
(1,2,7)
(1,3,6)
(1,4,5)
(1,9)
(2,3,5)
(2,8)
(3,7)
(4,6)
(10)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧