【发布时间】:2021-06-17 14:17:38
【问题描述】:
这是我的canSum 函数需要做的:
给定目标总和x,返回true,如果可以通过添加给定数组中的元素来获得该总和,假设数组元素可以使用任意次数。
例子:
canSum(7, {2,3}) -> true
canSum(7, {2,4}) -> false
下面是我用 C++ 重写的 JavaScript 代码。出于某种原因,即使我使用了 memoization,C++ 版本对于大输入也需要很长时间。
JavaScript 代码,运行良好:
const canSum = (targetSum, numbers, memo={}) => {
if (targetSum === 0) return true;
if (targetSum < 0) return false;
for ( let num of numbers) {
const remainder = targetSum - num;
if (canSum( remainder, numbers, memo) === true) {
return true;
}
}
return false;
};
console.log(canSum(7, [2, 3])); // true
console.log(canSum(7, [5, 3, 4, 7])); // true
console.log(canSum(7, [2, 41])); // false
console.log(canSum(8, [2, 3, 5])); // true
console.log(canSum(300, [7, 14])); // false
我的 C++ 代码,它从未为最后一个输入项提供任何输出 canSum(300, {7,14})
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,bool> mymap;
bool canSum(int goal, vector<int> vec)
{
if (goal<0) return false;
if (goal==0) return true;
if (mymap[goal]) return mymap[goal];
for(auto&ell:vec)
{
if(canSum(goal-ell,vec)==true)
{
mymap.insert({goal,true});
return true;
}
}
mymap.insert({goal,false});
return false;
}
int main()
{
cout<<canSum(7, {2,3})<<endl;
cout<<canSum(7, {5,3,4,7})<<endl;
cout<<canSum(7, {2,4})<<endl;
cout<<canSum(8, {2,3,5})<<endl;
cout<<canSum(300, {7,14})<<endl;
return 0;
}
如何优化 C++ 代码,为什么 JavaScript 代码更快?
【问题讨论】:
-
为什么js代码比较快? -- C++代码慢的证据在哪里?询问“为什么这么慢?”的问题将随附所使用的编译器、用于构建应用程序的编译器选项、是否在打开优化的情况下构建,以及具有测试和输出此信息的计时功能的实际 C++ 代码(或代码在在线性能测试员)。
-
javascript 可能通过引用传递对象,而
C++传递一个副本,除非你告诉它不同。也许试试bool canSum(int goal, vector<int> const& vec)?也使用优化进行编译。 -
if (mymap[goal]) return mymap[goal];-- 你在这里的意图是什么?如果是搜索地图看goal是否已经在地图中,那行代码不会这样做。一个从另一种语言逐行翻译到 C++ 的经典案例,然后失败了。 -
请注意,在 C++ 中使用
[ ]访问地图将自动插入一个条目,如果该条目不在地图中。另一个问题 - 您可能会通过在该行上使用[ ]两次来进行两次查找。基本上,需要重写那行代码才能进行一次实际的搜索一次,并根据值是否存在,用该值做一些事情。 unordered_map 有一个你应该使用的find()方法,而不是盲目地使用[ ]。find()将返回一个指向现有项目的迭代器,如果项目不存在,则返回end()。 -
您似乎没有在两次调用 canSum() 之间重置您的 global 映射对象。
标签: javascript c++ dynamic-programming memoization