c++ - 用C++ 17的功能方式做笛卡尔积

标签 c++ functional-programming c++17 cartesian-product

我正在尝试使用闭包/自定义函数来实现笛卡尔乘积,闭包是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)
}
首先,使用第一个 vector 的每个元素,迭代第二个 vector ,然后将应用函数的结果存储在结果 vector 中。
该代码仅用于表示目的。它不会编译。除其他外,它给出'b' is not captured in {vector<int>::iterator p = b.begin();错误。
如何纠正此代码和/或如何正确地使用闭包实现笛卡尔运算?

最佳答案

您的编译问题是因为您没有在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开始,添加了范围和 View ,因此您可以变得更具创意:
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循环可能是笛卡尔乘积的最佳方法,但是这应该使您体会到令人兴奋的可能性。
这是demo

关于c++ - 用C++ 17的功能方式做笛卡尔积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64405625/

相关文章:

c++ - STL 中令人烦恼的解析 scott meyers

function - 函数式编程中的所有纯函数都是连续的吗?

c++ - 如何使用 C++14 和 C++1z 中的功能缩短此可变参数模板代码?

java - 为什么在 C++ 中使用 this->ObjectName 而不是 this.ObjectName

c++ - 如何专门化所有引用类型的类 C++03

c++ - shared_ptr to map populated in a method 在调用者中返回空

javascript - 如何在不改变也不重新分配的情况下实现可设置和可检索的状态?

scala - 是否可以写一个不可变的双向链表?

c++ - 'make_unique' 不是 'std' 的成员

C++ 模板 - 完整指南 : Wording of footnote about decltype and return type