liberize
2015-12-09 12:37:28 +08:00
贴一个可行的解法,应该可以优化:
#include <iostream>
using namespace std;
const char *data[] = {"AB", "C", "ACF", "BE", "EF", "D", "AC", "CD", "ABF"};
int size = sizeof(data) / sizeof(char *);
void find(int start, int *selected, int step, unsigned status)
{
for (int index = start; index < size; index++) {
const char *item = data[index], *first;
// 检测是否现有的选择冲突(即有重复的项)
for (first = item; *first != '\0'; first++) {
if (status & (1 << (*first - 'A'))) {
break;
}
}
if (*first != '\0') {
continue;
}
// 没有冲突,选择它
for (first = item; *first != '\0'; first++) {
status |= 1 << (*first - 'A');
}
selected[step] = index;
// 检测是否包含所有项
if ((status & 0x3f) == 0x3f) {
for (int i = 0; i <= step; i++) {
cout << data[selected[i]] << ", ";
}
cout << endl;
} else {
// 没有包含所有项,继续从下一个开始尝试
find(index + 1, selected, step + 1, status);
}
// 回退,取消本次选择
for (first = item; *first != '\0'; first++) {
status &= ~(1 << (*first - 'A'));
}
}
}
int main(int argc, char const *argv[])
{
int selected[6] = {0};
find(0, selected, 0, 0);
return 0;
}
输出:
AB, C, EF, D,
AB, EF, CD,
ACF, BE, D,
其中, status 的低 6 位表示当前哪些项已经出现。