在 C++17 中以函数方式计算笛卡尔积

问题描述 投票:0回答:2

我正在尝试使用闭包/自定义函数来实现笛卡尔积,闭包是

function(x,y) = pow(x,2) + pow(y,2)
并以功能方式实现它,即不使用C风格循环。

这是我的看法。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
void print (vector<int> aux) {
  vector<int>::iterator it = aux.begin();
  while(it != aux.end()){
    cout << *it << " ";
    it++; }}

int main() {
  vector<int> a{1,2};
  vector<int> b{3,4};
  vector<int> cartesian(4);
  transform (a.begin(), a.end(), b.begin(), cartesian.begin(), [](int &i)
         {vector<int>::iterator p = b.begin();
           for_each(begin(b), end(b), [](int &n) { return pow(i,2) + pow(n,2) })});
  print(cartesian);
  // desired output is: 10,17,13,20 (cartesian operation)
}

首先,使用第一个向量的每个元素,迭代第二个向量,然后将应用函数的结果存储在结果向量中。

该代码用于表示目的。它无法编译。它会给出

'b' is not captured in {vector<int>::iterator p = b.begin();
错误等。

如何纠正此代码和/或如何使用闭包正确实现笛卡尔运算?

c++ functional-programming c++17 cartesian-product
2个回答
3
投票

您的编译问题是因为您没有捕获 lambda 中所需的变量,并且缺少一些

;

但是,进行笛卡尔积的更简单方法是使用 2 个嵌套循环,如下所示:

for (int i : a)
  for (int j : b)
    cartesian.push_back(i * i + j * j);

如果你想使用算法,那么你可以写:

for_each(begin(a), end(a), [&](int i) { 
  for_each(begin(b), end(b), [&](int j) { 
    cartesian.push_back(i * i + j * j); 
  });
});

虽然我发现这更难阅读,而且并没有多大帮助,因为

for_each
是一种恰好有内置语言结构的算法,类似于
transform


从 c++20 开始,添加了范围和视图,因此您可以获得更多创意:

namespace rs = std::ranges;
namespace rv = std::views;

auto product = [=](int i) 
{
   auto  op = [=](int j) { return i * i + j * j;};

   return b | rv::transform(op);
};
  
rs::copy(a | rv::transform(product) 
           | rv::join,
         std::back_inserter(cartesian));

同样,原始的嵌套

for
循环可能是笛卡尔积的最佳方法,但这应该让您体验到令人兴奋的可能性。

这是一个演示


0
投票

使用 C++23,并且由于

std::views::cartesian_product
的引入,这个示例现在可以写为:

#include <print>
#include <ranges>
#include <vector>

auto main() -> int {
    const auto a = std::vector<int>{1, 2};
    const auto b = std::vector<int>{3, 4};
    for (const auto [x, y] : std::ranges::cartesian_product(a, b))
        std::print("{},", x*x + y*y); // output: 10 17 13 20
}

演示

© www.soinside.com 2019 - 2024. All rights reserved.