从集合中生成所有可能的有序子集

时间:2016-11-07 03:31:38

标签: c++ algorithm

我知道如何从包含bit twiddling的集合中生成所有可能的子集。例如,

//Get if nth position's bit is set
bool IsBitSet(int num, int bit)
{
    return 1 == ((num >> bit) & 1);
}

int subsetMaxIterCount = pow(2, someList.size());
for (int i = 0; i < subsetMaxIterCount; i++) {
    vector<A> subset;
        for (size_t i = 0; i < jobList.size(); i++)
        {
            if (IsBitSet(jobSubsetIdx, i)) {
                //Add to subset here
            }
        }

        //Here we have a subset for some i
    }

但是,这并未考虑订购。

例如,如果我有一组{1,2,3},则上述算法会生成以下子集:

{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}

我现在需要的是这个

{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3},{2,1}, {2,1,3},{2,3,1},{3,1},{3,2},{3,1,2},{3,2,1}

不确定以上列表是否详尽无遗。生成这样的东西有什么有效的算法? (这是所有可能的子集,顺便说一下排列吗?)

1 个答案:

答案 0 :(得分:3)

我们使用bit twiddling生成子集的方式,每个子集都在其中排序e.g. {1, 2, 3}, {2, 3}, {1, 3}。您可以使用next_permutation

为每个子集生成排列
vector<vector<int>> mySubsetGenerator(vector<vector<int>>& subsets) {
    vector<vector<int>> extendedSubset;
    for(int i = 0; i < subsets.size(); ++i) {
         do {
             extendedSubset.push_back(subsets[i]);
         } while(next_permutation(subsets[i].begin(), subsets[i].end()));
    }
    return extendedSubset;
}

此外,您只能使用回溯来通过获取一个或多个数组元素来生成所有可能的排列。