您的位置:首页 > 其它

[CareerCup 8.3] 求一个集合的所有子集

2011-12-22 22:41 225 查看
这是一个很经典的问题,相对来说,也是比较简单的问题。首先,通过数学知识我们知道一个含n个元素的集合一共有2^n个子集。

方法1:采用递归的方法

举个例子来说{a, b, c}

我们可以先求{b, c}的所有子集{}, {b}, {c}, {b, c}

然后将{b, c}的所有子集与a进行组合与{b, c}的所有子集一起,形成{a, b, c}的所有子集

{}, {b}, {c}, {b, c}, {a}, {a, b}, {a, c}, {a, b, c}

代码如下:

/**
求一个集合的所有子集
我们可以递归来考虑这个问题
举个例子来说{a, b, c}
我们可以先求{b, c}的所有子集{}, {b}, {c}, {b, c}
然后将{b, c}的所有子集与a进行组合与{b, c}的所有子集一起,形成{a, b, c}的所有子集
{}, {b}, {c}, {b, c}, {a}, {a, b}, {a, c}, {a, b, c}
**/
vector<set<int>> subset(set<int> s)
{
if (s.empty())
return vector<set<int>>();
int b = *s.begin();
s.erase(s.begin());
vector<set<int>> v = subset(s);
vector<set<int>> result;
set<int> t;
result.push_back(t);
t.insert(b);
result.push_back(t);
for (vector<set<int>>::iterator it = v.begin(); it != v.end(); it++)
{
if (! it->empty())
{
set<int> n(*it);
n.insert(b);
result.push_back(*it);
result.push_back(n);
}
}
return result;
}


方法2:从二进制的观念来考虑

注意一个n个元素的集合有2^n个子集

比如一个集合{a,b,c}有8个子集

注意到求子集的时候,有个特点,我们就只要确定一个元素是否在子集中

比如所有的元素都不在子集中,那么这个子集为空集

如果所有的元素都在子集中,那么这个子集为这个集合本身

对于一个n个元素,可以用n位2进制来表示

比如{a, b, c}可以用3位2进制表示

0 000 {}

1 001 {a}

2 010 {b}

3 011 {a, b}

4 100 {c}

5 101 {a, c}

6 110 {b, c}

7 111 {a, b, c}

这种算法有一个问题,就是当集合的大小超过32后,就会溢出,但是考虑一下2^32个结果也基本上存不下了。

代码如下:

/**
注意一个n个元素的集合有2^n个子集
比如一个集合{a,b,c}有8个子集
注意到求子集的时候,有个特点,我们就只要确定一个元素是否在子集中
比如所有的元素都不在子集中,那么这个子集为空集
如果所有的元素都在子集中,那么这个子集为这个集合本身
对于一个n个元素,可以用n位2进制来表示
比如{a, b, c}可以用3位2进制表示
0 000 {}
1 001 {a}
2 010 {b}
3 011 {a, b}
4 100 {c}
5 101 {a, c}
6 110 {b, c}
7 111 {a, b, c}
**/
vector<set<int>> subset_two(set<int> s)
{
int count = s.size();
int i, j;
vector<set<int>> v;
for (i = 0; i < 1 << count; i++)
{
set<int> t;
j = 0;
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
if (get_bit(i, j++))
t.insert(*it);
}
v.push_back(t);
}
return v;
}


测试代码:

int main()
{
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
vector<set<int>> v = subset_two(s);
for (vector<set<int>>::iterator it = v.begin(); it != v.end(); it++)
{
for (set<int>::iterator sit = it->begin(); sit != it->end(); sit++)
cout << *sit << ' ';
cout << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: