我试图使用递归和记忆来创建“卡车问题”的解决方案。我想将缓存存储在无序映射中,并在递归运行之前获取映射值,我使用 contains。这是大约2小时前编译的,但是现在,以同样的方式编译它,它不起作用。 这是代码片段。
#include "EfficientTruckloads.h"
#include <unordered_map>
#include <string>
#include <iostream>
int EfficientTruckloads::numTrucks(int numCrates, int maxLoad) {
static std::unordered_map<std::string,int> memoization;
std::string name = std::to_string(numCrates) + "-" + std::to_string(maxLoad);
if(memoization.contains(name)) return memoization[name];
if (numCrates <= maxLoad) {
return 1;
}
if (numCrates % 2) {
memoization[name] = numTrucks(numCrates%maxLoad+numCrates/2, maxLoad) + numTrucks(numCrates/2, maxLoad);
}
memoization[name] = 2 * numTrucks(numCrates/2, maxLoad);
return memoization[name];
}
尝试使用编译器标签 -std=c++20,没有运气。使用 g++ 12.1.0。从现在到编译时,代码中没有发生任何变化。通过执行“g++ -std=c++20 *.cpp”进行编译。指定 .cpp 文件的名称也不会改变任何内容。这是其成员函数的类如下所示:
#ifndef EFFICIENTTRUCKLOADS_H
#define EFFICIENTTRUCKLOADS_H
class EfficientTruckloads {
public:
int numTrucks(int numCrates, int maxLoad);
};
#endif
完整错误消息: EfficientTruckloads.cpp:
In member function 'int EfficientTruckloads::numTrucks(int, int)':
EfficientTruckloads.cpp:8:24: error: 'class std::unordered_map<std::__cxx11::basic_string<char>, int>' has no member named 'contains'
在 C++ 中,说您想要编译器提供特定标准可以让您尽最大努力,并且通常不会自动包含完全更新的
std
库。
像这样的东西不起作用的常见原因是即使您使用正确的编译器,您也使用了错误的标准库,或者您的编译器没有实现您传递的标志。调试工具链是一种选择;另一个是回退到 c++17 解决你的问题。
foo.contains(x)
是一种方便的方法;在非多地图/集合上,它可以免费替换为 foo.count(x) != 0
以获得相同的性能和语义。 (在无序容器的多种情况下,这可能会增加 O(匹配的元素数量)额外成本;如果您真的关心的话,迭代器 foo.find(x) != foo.end()
实现可以避免这种情况)。
对于大多数语言,标准描述了唯一的参考编译器已经做了和已经实现的内容;因此,与标准的差异是文档或实施的错误。
在C++中,标准首先改变,然后多个不同的编译器都实现它。因此,您经常会得到一个具有给定 C++ 标准的部分实现的编译器。 当他们的实现基于标准最终确定之前的早期草案时,他们通常会使用标准的非正式代码词,例如
c++2a
而不是
c++20;使用这样的标志通常会做你想做的事。 在这种情况下,我只需使用
.count()
技术。