使用递归时如何摆脱这个全局变量?

时间:2016-10-07 07:08:41

标签: c++ algorithm recursion

首先,我不想使用sort。这只是一个例子。这个问题的主要目的是我想:

  

查找m个数字中n个数字的所有可能组合    处理它们,然后返回唯一的处理结果(因为   将比较所有可能组合的处理结果。)

问题从这里开始

以下代码获取M个数字中所有可能的组合N个数字。求和M数字并找到最大的总和。在这样做时,我使用了递归函数。

但是,似乎我必须定义一个全局变量来存储临时最大的和。有没有办法摆脱这个全局变量?例如,定义递归函数以返回最大的总和...我不希望全局变量在&max_sum中成为参数find_sum,因为find_sum已经有太多的争论。

#include <iostream>
#include <vector>

void find_sum(const std::vector<int>& ar, std::vector<int>&  combine,
        int index, int start);

int max_sum =0;

int main()  {
    int N = 10;
    int M = 3;
    std::vector<int> ar(N); 
    ar = {0,9,2,3,7,6,1,4,5,8};

    int index = 0, start =0;
    std::vector<int> combine(M);
    find_sum(ar, combine, index, start);
    std::cout << max_sum <<std::endl;
    return 0;
}

void find_sum(const std::vector<int>& ar, std::vector<int>&  combine, 
        int index, int start) {

    if(index == combine.size())  {
        int sum =0;
        for(int i=0; i<index; ++i)  {
            sum += combine[i];
        }
        if(max_sum < sum)   {
            max_sum = sum;
        }
        return ;
    }

    for(int i = start; 
            i < ar.size() && ar.size()-i > combine.size()-index; 
            ++i) {
        combine[index] = ar[i];
        find_sum(ar, combine, index+1, start+1);
    }
}

3 个答案:

答案 0 :(得分:2)

可以很好地扩展的方法是将 cur.execute(updt_query,(19,1)) 转换为函数对象。诀窍是定义一个带有重载find_sum运算符的struct,该运算符需要一组参数:

()

然后实例化struct FindSum { void operator()(const std::vector<int>& ar, std::vector<int>& combine, int index, int start){ /*ToDo - write the function here, a very explicit way of /*engineering the recursion is to use this->operator()(...)*/ } int max_sum; // I am now a member variable }; ,如果需要设置FindSum find_sum;(甚至可以在构造函数中设置),然后使用{{1}调用重载的find_sum.max_sum运算符}}

此技术允许您将 state 传递给本质上是函数。

答案 1 :(得分:2)

find_sum,返回最远的最大总和(而不是void)。这意味着递归终止代码将是:

if(index == combine.size())  {
        int sum =0;
        for(int i=0; i<index; ++i)  {
            sum += combine[i];
        }
        return sum;
    }

,递归部分将是

int max_sum = 0;
for(int i = start; 
            i < ar.size() && ar.size()-i > combine.size()-index; 
            ++i) {
        combine[index] = ar[i];
        int thismaxsum = find_sum(ar, combine, index+1, start+1);
        if(thismaxssum > max_sum)
            max_sum = thismaxsum;
}
return max_sum;

因此,整体解决方案是:

#include <iostream>
#include <vector>

int find_sum(const std::vector<int>& ar, std::vector<int>&  combine,
    int index, int start);


int main() {
    int N = 10;
    int M = 3;
    std::vector<int> ar(N);
    ar = { 0,9,2,3,7,6,1,4,5,8 };

    int index = 0, start = 0;
    std::vector<int> combine(M);
    int max_sum = find_sum(ar, combine, index, start);
    std::cout << max_sum << std::endl;
    return 0;
}

int find_sum(const std::vector<int>& ar, std::vector<int>&  combine,
    int index, int start)
{
    if (index == combine.size())
    {
        int sum = 0;
        for (int i = 0; i<index; ++i)
        {
            sum += combine[i];
        }
        return sum;
    }

    int max_sum = 0;

    for (int i = start;
        i < ar.size() && ar.size() - i > combine.size() - index;
        ++i)
    {
        combine[index] = ar[i];
        int thismaxsum = find_sum(ar, combine, index + 1, start + 1);
        if (thismaxsum > max_sum)
            max_sum = thismaxsum;
    }

    return max_sum;
}

答案 2 :(得分:0)

全局变量比将操作数和变量添加到递归函数要好得多,因为每个操作数和变量导致堆/堆栈废弃会对性能和空间使用产生负面影响,从而有可能导致堆栈溢出,从而实现更高的递归。

为了避免全局变量(对于代码化妆品和多线程/实例化目的),我通常使用context或temp结构。例如:

// context type
struct f1_context
 {
 // here goes any former global variables and stuff you need
 int n;
 };

// recursive sub function
int f1_recursive(f1_context &ctx)
 {
 if (ctx.n==0) return 0;
 if (ctx.n==1) return 1;
 ctx.n--;
 return (ctx.n+1)*f1_recursive(ctx.n);
 }

// main API function call
int f1(int n)
 {
 // init context
 f1_context ctx;
 ctx.n=n;
 // start recursion
 return f1_recursion(ctx);
 }

f1(n)是阶乘的例子。这样操作数限于指向结构的单个指针。粗略的,您可以在上下文之后添加任何递归尾部操作数...上下文仅用于全局和持久性的东西(即使我确实将它用于递归尾部,但这并不总是可行)。