0

我想编写用于邻接矩阵的最大团算法。我正在观看一段视频,该视频解释了如何使用 Python 编写和实现算法。我目前正在尝试在视频 2 分钟后对 powerset 功能进行编码。

def powerSet(elts):
    if len(elts) == 0:
        return [[]]
    else:
        smaller = powerSet(elts[1:])
        elt = [elts[0]]
        withElt = []
        for s in smaller:
            withElt.append(s + elt)
        allofthem = smaller + withElt
    return allofthem

print powerSet([1, 2, 3, 4, 5])

我想用 C++ 重写它。我不确定我是否应该使用数组。到目前为止,我已经编写了以下代码,但我不知道如何在空数组中返回一个空数组(当elts list大小为 0 时)。

我为数组编写了一个isEmpty函数,因为我不能len(elts)像在 Python 中那样使用。我的方法可能不是最好的方法,所以我愿意接受任何建议。

更新:

array powerSet(int elts[])
{
     if (isEmpty(elts)==1)
     {
          return {{}};
     }

}

在我的 int main 我有:

list<int> elts;

list<int>::iterator i;

for (i=elts.begin(); i != elts.end(); ++i)
      cout << *i << " ";
      cout << endl;

powerSet(elts);    

我不知道从这里做什么。

代码应该使用我们称之为“elts”(元素的缩写)的array// 。然后首先,它应该添加空列表,然后是电源集的其余部分(全部显示在视频中)。listvector[]

例如,在这种情况下elts = [1,2,3,4],我的代码应该返回:

`[ [],[4],[3],[4,3],[2],[4,2],[3,2],[4,3,2],[1],[4,1],[3,1],[4,3,1],[2,1],[4,2,1],[‌​3,2,1],[4,3,2,1] ]  `  

我不知道如何使用array//来做上面的事情listvector

4

1 回答 1

0

这是 Python 代码的相当直译

#include <vector>
using std::vector;
#include <iostream>
using std::cout;

//def powerSet(elts):
vector<vector<int>> powerSet(const vector<int>& elts)
{
//  if len(elts) == 0:
    if (elts.empty()) {
//      return [[]]
        return vector<vector<int>>(
            1, // vector contains 1 element which is...
            vector<int>()); // ...empty vector of ints
    }
//  else:
    else {
//      smaller = powerSet(elts[1:])
        vector<vector<int>> smaller = powerSet(
            vector<int>(elts.begin() +1, elts.end()));
//      elt = [elts[0]]
        int elt = elts[0]; // in Python elt is a list (of int)
//      withElt = []
        vector<vector<int>> withElt;
//      for s in smaller:
        for (const vector<int>& s: smaller) {
//          withElt.append(s + elt)
            withElt.push_back(s);
            withElt.back().push_back(elt);
        }
//      allofthem = smaller + withElt
        vector<vector<int>> allofthem(smaller);
        allofthem.insert(allofthem.end(), withElt.begin(), withElt.end());
//      return allofthem
        return allofthem;
    }
}

vector<int>用于整数集。然后是其中的一个vector,即vector<vector<int>>整数集的列表。你特意问了一件事

我不知道如何在空数组中返回一个空数组(当elts list大小为 0 时)。

第一条语句使用构造函数return返回一个包含一个元素的列表,即空集,其第一个参数是 中的元素数,第二个参数是要重复次数的元素。一个等效但更冗长的替代方案是vectornvectorn

    vector<vector<int>> powerSetOfEmptySet;
    vector<int> emptySet;
    powerSetOfEmptySet.push_back(emptySet);
    return powerSetOfEmptySet;

我试图保持代码简单,避免太多深奥的 C++ 特性。希望您可以在一个好的参考资料的帮助下完成它。使用的一个 C++ 习语是将一个向量附加到另一个向量,如allofthem.insert(allofthem.end(), withElt.begin(), withElt.end());.

同样在比 Python“更接近金属”的 C++ 中,您可能只使用一个vector来代替三个向量smaller,withEltallofthem. 这导致下面的代码更短、更优化。

//def powerSet(elts):
vector<vector<int>> powerSet(const vector<int>& elts)
{
//  if len(elts) == 0:
    if (elts.empty()) {
//      return [[]]
        return vector<vector<int>>(1, vector<int>());
    }
//  else:
    else {
//      smaller = powerSet(elts[1:])
        vector<vector<int>> allofthem = powerSet(
            vector<int>(elts.begin() +1, elts.end()));
//      elt = [elts[0]]
        int elt = elts[0]; // in Python elt is a list (of int)
//      withElt = []
//      for s in smaller:
//          withElt.append(s + elt)
//      allofthem = smaller + withElt
        const int n = allofthem.size();
        for (int i=0; i<n; ++i) {
            const vector<int>& s = allofthem[i];
            allofthem.push_back(s);
            allofthem.back().push_back(elt);
        }
//      return allofthem
        return allofthem;
    }
}

下面的测试代码

int main()
{
    const int N = 5;
    vector<int> input;
    for(int i=1; i<=N; ++i) {
        input.push_back(i);
    }
    vector<vector<int>> ps = powerSet(input);
    for(const vector<int>& set:ps) {
        cout << "[ ";
        for(int elt: set) {
            cout << elt << " ";
        }
        cout << "]\n";
    }
    return 0;
}

作为脚注,我对从 Python 转换为 C++ 的简单程度感到惊喜。我读过使用 Python 编写(或原型)算法,然后在必要时用 C++ 等语言重写可能是有意义的,但是,正如谚语所说,眼见为实。


这是适用于 C++98 的程序版本。我恢复了我使用的基本 C++11 功能(>>在模板声明和基于范围的情况下for)。

#include <vector>
using std::vector;
#include <iostream>
using std::cout;

vector<vector<int> > powerSet(const vector<int>& elts)
{
    if (elts.empty()) {
        return vector<vector<int> >(1, vector<int>());
    }
    else {
        vector<vector<int> > allofthem = powerSet(
            vector<int>(elts.begin() +1, elts.end()));
        int elt = elts[0];
        const int n = allofthem.size();
        for (int i=0; i<n; ++i) {
            const vector<int>& s = allofthem[i];
            allofthem.push_back(s);
            allofthem.back().push_back(elt);
        }
        return allofthem;
    }
}

int main()
{
    const int N = 5;
    vector<int> input;
    for(int i=1; i<=N; ++i) {
        input.push_back(i);
    }
    vector<vector<int> > ps = powerSet(input);
    for(vector<vector<int> >::const_iterator i=ps.begin(); i!=ps.end(); ++i) {
        const vector<int>& set = *i;
        cout << "[ ";
        for(vector<int>::const_iterator j=set.begin(); j!=set.end(); ++j) {
            int elt = *j;
            cout << elt << " ";
        }
        cout << "]\n";
    }
    return 0;
}
于 2014-04-06T22:41:47.400 回答