【问题标题】:How to reset a static vector inside a function?如何重置函数内的静态向量?
【发布时间】:2014-06-07 18:42:52
【问题描述】:

我正在尝试使用 动态编程 范式解决在线法官的某个问题。我写了一个函数来记忆较小的子问题的结果。但是这个函数将在一次运行中被调用 t 次。因此,当函数调用自身时,我希望保留它的 "Memory",但是当从驱动程序调用它时,我不想重置向量。我怎么做?我认为有一个全局向量并在每次从驱动程序调用后重置它是可能的,但正如我从书籍和堆栈溢出中了解到的那样,“糟糕的编程风格”。那么这个问题有什么好的解决方案呢?代码如下:

class mem{
public:    
        bool mike_win;
    bool written;

};
bool calc(int a){
    static vector<mem> memory(a);
    if( a == 1){
            return false;
    }
    if(memory[a-1].written == true){
        return (!(memory[a-1].mike_win))
    }
    vector<int> div_list = divis(a);
        //^^ divis is a function which takes a number and returns 
        //all its divisors in descending order in a vector<int>

    for(vector<int>::iterator i = div_list.begin();i != div_list.end();i++){
        if ( ! ( calc( a / (*i) ))){
            memory[a-1].written = true;
            memory[a-1].mike_win = true;
            return true;
        }
    }
    if(calc(a-1 ) == false){
        memory[a-1].written = true;
        memory[a-1].mike_win = true;
        return true;
    }
    else{
        memory[a-1].written = false;
        memory[a-1].mike_win = false;
        return false;
    }

}

这里是question. 的链接,这里是divis 函数:

vector<int> divis(int a){

    vector<int> div_list(int a )
        if(a==2){
                return div_list;
        }
        int k = sqrt(a);
        for(int i=2;i<=k;i++){
            if(!(a%i)){
                    div_list.push_back(i);
                    div_list.push_back(a/i);
            }
        }
        sort(div_list.rbegin(),div_list.rend());
        div_list.erase(unique(div_list.begin(),div_list.end()),div_list.end());
        return div_list;
}

【问题讨论】:

  • 您想在究竟发生什么时重置memory
  • 你可以清除然后调整它的大小。您可能想要添加一个附加参数,以便知道何时执行此操作。这是一个用于比赛的一次性程序,我只是使用全局,使其成为静态真的不是更漂亮。
  • @Jeffery 递归完成后我想重置内存。 @Retired Ninja 你建议我添加什么额外的参数?还有什么更漂亮的方式?
  • 计算似乎对等于向量大小的a 的某个值有效。当 a 与静态向量的大小不同时,使结果无效还不够吗?
  • @user2672165 是的,但在所有情况下,对函数的调用都是使用 a

标签: c++ vector static dynamic-programming memoization


【解决方案1】:

我认为我会这样做的方法是创建两个calc 的重载:一个只接受int 作为参数,另一个接受一个int 和一个对vector&lt;int&gt; 的引用。这样,用户将调用第一个重载,它将创建用于记忆的临时向量,并将其传递给第二个函数,该函数在递归时传递引用。有点像这样:

bool calc(int a, vector<int>& memory)
{
    // Do your stuff here
    // Instead of calling it as calc( a / (*i) ), just call
    // it as calc( a / (*i) , memory )
}

bool calc(int a)
{
    vector<int> memory(a);
    calc(a, memory);
}

这样,您就不必在算法的核心进行任何类型的簿记以确定是否清除向量;它会在第一次调用返回后自动完成。

【讨论】:

  • 非常优雅的解决方案。谢谢。但我想知道它是否比我的(错误)实现慢。如果是的话,多少。 t 大约为 10^4
  • @SoumadeepSaha 如果有的话,它会更快;您不必在每次通话时检查是否应该清除它。这将是一个最小的加速,但更重要的是,它使函数更简洁。
猜你喜欢
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
相关资源
最近更新 更多