看书上有个例子,讲的是求数组元素的排列。
MD,上来第一遍完全没看懂,于是接着看几遍又没看懂,打击不小,才买的书啊!没办法,只好耐下性子,慢慢看,一步一步理解。最后终于是看懂了。
代码:(递归实现)
/*
{a, b, c}: a {b, c} + b {a, c} + c {a, b}
将第一个元素先拿出来,然后与后面的一个一个进行交换,不断的对后面的集合重复这个
*/
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
inline void Swap(T & a, T & b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template <typename T>
void Perm(T list[], int k, int m)
{
int i;
if(k == m)
{
for(i = 0; i <= m; i++)
cout << list[i];
cout << endl;
}
else
{
//for(i = k; k <= m; i++) //是i<=m,不是k<=m ,才开始把这个搞错了。。。
for(i = k; i <= m; i++)
{
Swap(list[k], list[i]);
Perm(list, k+1, m);
Swap(list[k], list[i]); //变回原来的位置
}
}
}
int main()
{
char ch[] = {'a', 'b', 'c'};
Perm(ch, 0, 2);
return 0;
}
然后后面有一个习题是求集合的子集:(也就是组合)
又是想了很长时间又是没想出来,唉。。。后来参考很多,不过答案都很繁琐,这个算是很简单的了。
/*
一个元素要么在这个集合,要么不在这个集合。所以设置int mask[] ;来记录某个元素在不在这个集合。
为0表示不在,为1表示在 。
举例:
a[n]所有的子集为 : a[0]存在加上后面的n-1个元素的集合
a[0]不存在加上后面的n-1个元素的集合
*/
#include <iostream>
using namespace std;
template <typename T>
void subset(T * s, int * m, int size, int c)
{
if(c == size)
{
for(int i = 0; i < size; i++)
if(m[i] == 1) //这一部才开始居然没想到
cout << s[i];
cout << endl;
}
else
{
m[c] = 0; //这个元素不在这个集合
subset(s, m, size, c+1);
m[c] = 1; //这个元素在这个集合
subset(s, m, size, c+1);
}
}
int main()
{
char s[3] = {'a', 'b', 'c'};
int m[3] = {0}; //初始状态下全为0
subset(s, m, 3, 0);
return 0;
}