我有一个旨在执行递归计算的函数。如果我的函数是递归编程的,那么计算时间太长。因此,我通过将中间结果存储在数组中来执行memoization。
在我的程序执行期间,我可能会使用参数(10,0)
,(5,5)
,(2,4)
等来调用该函数。因此,我有一个setup(double x)
函数可以填充整个具有正确值的数组。然后我可以访问任何数组值而无需进一步计算。我只等到x
更改后再次致电setup()
。
我想知道如何在c ++中实现它。我使用类没有意义,因为我永远不需要创建关联的对象。我已经在命名空间中实现了很好的功能,但我仍然遇到了问题。即使我使用未命名的命名空间,我的函数使用的数组也是可见的,并且可以从函数的命名空间外部进行修改。如果我包含命名空间的头文件,那就是。
我的代码:
FunctionWrapper.h
namespace FunctionWrapper{
namespace{
double tempArray[10][10];
}
void setup(double x);
void getValues(int n);
}
Main.cpp的
#include "FunctionWrapper.h"
int main(){
FunctionWrapper::tempArray[0][0] = 5; //Works
}
答案 0 :(得分:6)
如果您不希望tempArray
在其他源文件中可以命名,请不要在头文件中声明它。而是在 FunctionWrapper.cpp 中的未命名命名空间中声明它。然后,它只能直接在该源文件中使用。
通常,头文件不应使用未命名的命名空间,因为它可能(并且经常会)导致违反一个定义规则。
请注意,更好的解决方案可能是创建一个提供此功能的类:
class ValueGetter
{
public:
ValueGetter(double x);
void GetValues(int n);
private:
double cache[10][10];
};
这样,您可以创建此类型的实例,并且该实例拥有所有状态。避免全局状态有很多好处,包括提高可维护性和可测试性。
答案 1 :(得分:1)
这作为一个类有意义,而那些函数作为该类的成员。这些函数对这些数据起作用,你不希望任何其他人访问这些数据,这听起来像是一个完美的类。你为什么反对呢?
答案 2 :(得分:1)
继詹姆斯(通常,优秀)答案之后,我会构建类似这样的东西:
namespace {
class value_cache {
double temp_array[10][10];
int x;
void setup(double x);
void internal_getValues(int); // same as your current GetValues
public:
void getValues(int n) {
if (x != n)
setup(x=n);
internal_getValues(n);
}
};
}
double function(int x, int y) {
static value_cache c;
c.getValues(x);
// probably more stuff here.
}
答案 3 :(得分:0)
我在这里看到三个选项:
.cpp
文件中。然后它将无法从其他任何地方进行访问。static
变量。operator ()
的类,并使用它的实例作为“函数”。然后memoization数组可以是该类的私有成员变量。选项1非常简单,它会起作用。当然,如果您的函数曾经在多线程环境中使用过,那么您将不得不考虑访问memoized value数据结构的线程间同步。
选项2是选项1的变体。就个人而言,我认为这是你应该选择的那个。它有完全相同的缺点。
选项3是,恕我直言,相当繁琐。为了拥有看起来像你的函数一样的东西,你必须声明一个类的全局变量。但这基本上是一个单身人士。虽然在这种情况下可能没问题,但最终可能会成为一个巨大的痛苦。
还有另一种选择,但这是一项大量的工作。它基本上是一个记忆模板。它将像选项3一样运行,但您可以为任何参数满足作为hashmap键的标准的函数实例化它。