javascript - 将 JavaScript 函数转换为 C++
问题描述
我正在研究一个动态编程问题,并且能够编写一个 Javascript 解决方案:
function howSum(targetSum,numbers,memo = {}){
//if the targetSum key already in hashmap,return its value
if(targetSum in memo) return memo[targetSum];
if(targetSum == 0) return [];
if(targetSum < 0) return null;
for(let num of numbers){
let aWay = howSum(targetSum-num,numbers,memo);
if(aWay !== null){
memo[targetSum] = [...aWay,num];
return memo[targetSum];
}
}
//no way to generate the targetSum using any elements of input array
memo[targetSum] = null;
return null;
}
现在我正在考虑如何将其转换为 CPP 代码。我将不得不使用unordered map
对memo
对象的引用。
但是我应该如何在基本条件中返回empty array
and值?我应该在插入元素时返回 an and it 吗?这不是一种编程方式吗?另外,我应该如何将 传递给C++ 中的无序映射?目前我已经重载了创建备忘录无序映射并传递它的函数。null
array pointer
realloc
C
default parameter
memo
reference
任何指导将不胜感激,因为我可以解决未来的问题。
解决方案
这是我的看法:
#include <optional>
#include <vector>
#include <unordered_map>
using Nums = std::vector<int>;
using OptNums = std::optional<Nums>;
namespace detail {
using Memo = std::unordered_map<int, OptNum>>;
OptNums const & howSum(int targetSum, Nums const & numbers, Memo & memo) {
if (auto iter = memo.find(targetSum); iter != memo.end()) {
return iter->second; // elements are std::pair<int, OptNums>
}
auto & cached = memo[targetSum]; // create an empty optional in the map
if (targetSum == 0) {
cached.emplace(); // create an empty Nums in the optional
}
else if (targetSum > 0) {
for (int num : numbers) {
if (auto const & aWay = howSum(targetSum-num, numbers, memo)) {
cached = aWay; // copy vector into optional
cached->push_back(num);
}
}
}
return cached;
}
} // detail
std::optional<Nums> howSum(int targetSum, Nums const & numbers) {
detail::Memo memo;
return detail::howSum(targetSum, numbers, memo);
}
一些评论:
使用两个函数,一个创建备忘录并将其传递给真正的实现函数是一种很好的模式。它使面向用户的界面变得干净。
“detail”命名空间只是一个名字,没有什么神奇的含义,但经常用来表示实现细节。
在实现中,我返回对可选的引用。这是避免在算法从递归中展开的每次调用中复制返回向量的优化。然而,这确实需要一些小心,因为您必须小心返回对将超过本地范围的对象的引用(例如,不返回 std::nullopt,或者引用绑定到临时可选。)这也是为什么我总是在备忘录对象中创建元素——即使在否定的情况下——所以我可以安全地返回对它的引用。请注意,应用于 unordered_map 的 operator[] 将创建该元素,如果它不存在,则
find
不会。由于detail函数返回的引用只有在调用者中声明的备忘录的生命周期,调用者本身必须返回它返回的可选的副本,以确保在函数清理过程中数据不被破坏称呼。请注意,它不返回引用。
此外,for 循环中的“if”也有一些变化。它声明一个本地引用,将其初始化为递归调用的结果。
bool
整个表达式是对 optional 的引用,如果 optional 持有一个值,它会隐式转换为 true。这是一个值得指出的有用习语,但更明确地说,这是等价的:
if (auto const & aWay = howSum(targetSum-num, numbers, memo); aWay.has_value())
这是一个充实的示例,并带有一些测试用例来证明它是有效的。 https://godbolt.org/z/cWrdhvM1n
推荐阅读
- python - 熊猫:无法合并两个日期列
- android - Android BottomNavigationView 每次使用导航组件重新创建片段
- python - 我的代码冻结并停止,它有什么问题?
- javascript - 咕哝着反应原生
- flutter - 错误:参数类型“Null”不能分配给参数类型“Map”
' - .net - 什么是 .NET 5.0.2 和 5.0.4?
- haskell - 如何使用列表理解计算两个列表的对称差异?
- laravel-8 - 此集合实例上不存在属性 [名称]
- windows - 有没有办法在powershell的随机列表中获取项目的索引
- arrays - 垃圾值在使用 CodeBlock 执行 C 文件时很普遍