合并成员函数在约束向量向量上的级联应用

时间:2014-03-24 15:49:41

标签: c++ algorithm combinations

我有以下矢量矢量:

V = std::vector<std::vector<MyType> >

V中包含的载体不一定具有相同的长度。 MyType有一个成员函数与以下签名合并:

bool MyType::merge(MyType in, MyType &out);

此成员函数使用self和in并检查它们是否可以合并为out。如果是,则将out设置为合并结果和 函数返回true。否则返回false并且不会修改out。

我想通过V中的每个向量来获取所有可能的组合合并到最终结果std :: vector中。举个例子, 如果V包含三个向量A,B,C,每个有3个元素,我想得到一个具有以下结果的向量:

A_0 - B_0 - C_0
A_0 - B_0 _ C_1
A_0 - B_0 _ C_2
A_0 - B_1 - C_0
A_0 - B_1 _ C_1
A_0 - B_1 _ C_2
A_0 - B_2 - C_0
A_0 - B_2 _ C_1
A_0 - B_2 _ C_2
A_1 - B_0 ... etc

如果合并返回false,则合并后的结果应该在结果向量中。

解释有点冗长,但我觉得这应该不是很困难,我觉得有一个 使用某些stl功能完成此操作的简单方法,但我根本看不到它。

1 个答案:

答案 0 :(得分:0)

这听起来像一个非常递归的问题,它正在合并向量元素的N维笛卡尔积:

您希望将A的每个元素与合并B,C,......中的合并元素的所有可能组合的所有结果合并,并将其放入结果向量,即将第一个维度与笛卡尔合并的结果合并其余N-1维的产物。递归的结束是最后一个维度:

typedef std::vector<std::vector<MyType>>::const_iterator vvIter;
std::vector<MyType> cartesianMerge(vvIter start, vvIter end) {

   auto const& currentVector = *start;

   if (start+1 == end) return currentVector; //end recursion

   auto mergeWith = cartesianMerge(start+1, end); //recursie

   std::vector<MyType> results;
   MyType temp;
   for (auto const& lhs : currentVector)
     for (auto const& rhs : mergeWith )
        if (lhs.merge(rhs, temp)) results.push_back(temp);

   return results;
}

int main() {
  auto v = std::vector<std::vector<MyType> >{ /* ... you fill it! ... */ };

  auto allMerged = cartesianMerge(std::begin(v), std::end(v));
}

这可以使用像std::transform之类的标准算法来推广,但由于它是一个条件转换(如果合并失败,则没有结果),它看起来不会更清晰。