数据结构中说这个问题可以用类似8皇后的状态树解法。
把求解过程看成是一棵二叉树,空集作为root,然后遍历给定集合中的元素,左子树表示取该元素,右子树表示舍该元素。
然后,root的左右元素分别重复上述过程。
就形成了一个递归。
集合使用List--单链表来存储,这样能保证,取和舍都只影响链表中的一个节点。
代码如下:
#include <iostream>
using namespace std;
/**
*单链表的实现。
*/
class Node{
public:
char ele;
Node * next;
Node(char ele): ele(ele), next(NULL){}
~Node(){if(next) delete next;}
void printNode(){
cout<<ele<<" ";
}
};
class list{
Node *header;
int length;
public:
list(): header(NULL), length(0){}
~list(){if(header)delete header;}
void addNode(Node *n){
if(header == NULL){
header = n;
length++;
}else{
Node *tmp = header;
while(tmp->next != NULL){
tmp = tmp->next;
}
tmp->next = n;
length++;
}
}
void deleteNode(char value){
if(header == NULL){
return;
}
Node *tmp = header;
Node *pre = header;
while(tmp!= NULL){
if(tmp->ele == value){
if(tmp == header){
delete header;
header = NULL;
}else{
pre->next = tmp->next;
tmp->next = NULL;
delete tmp;
length--;
}
}else{
pre = tmp;
tmp = tmp->next;
}
}
}
void printList(){
if(header == NULL || length == 0){
return;
}
Node* tmp = header;
while(tmp != NULL){
tmp->printNode();
tmp = tmp->next;
}
cout<<endl;
}
};
static list *l;//链表
const char *source;//源字符串
void getPowerSet(int i, int n);//函数声明
//初始化
void initSet(const char *src){
l = new list;
source = src;
}
//取操作
void addPowerSet(int i, int n){
l->addNode(new Node(source[i]));
getPowerSet(i + 1, n);
}
//舍操作
void deletePowerSet(int i, int n){
l->deleteNode(source[i]);
getPowerSet(i + 1, n);
}
//入口函数
void getPowerSet(int i, int n){
if(i > n){
cout<<"one result: ";
l->printList();//打印出一个结果,说明一个分支已经走完,拿到了一个子集。
return;
}else{
addPowerSet(i, n);//取
deletePowerSet(i, n);//舍
}
}
//main函数
int main(){
initSet("123");
getPowerSet(0, 2);
delete l;
return 0;
}