递归函数返回bool

时间:2017-12-07 21:27:17

标签: c++ arrays function recursion boolean

我无法理解返回bool的以下递归函数。

 bool p(int a[], int inf, int sup) {
    if(sup==inf)
        if(a[inf]>0)
            return true;
        else 
            return false;
    int m=(inf+sup)/2;
    bool left=p(a,inf,m);
    bool right=p(a,m+1,sup);
    return left && right;
}

如果(inf,sup)中的所有元素都是正数或者是假的,它应该返回true,但是我不能看到如何考虑不在数组的两个极值处的元素,因为条件经过测试的是a[inf]>0并且在left的递归过程中inf没有更改,而它只在right数组的右侧部分获取值。

所以基本上,因为它与更简单的递归(如阶乘或斐波纳契)不同,我无法理解递归在这里如何工作:我试图从基础案例开始并继续第二步但它是不清楚如何继续。

如果(inf,sup)中的所有元素都是正数,那么有人可以建议我如何遵循这种情况下的递归来理解这个函数如何返回true?

4 个答案:

答案 0 :(得分:2)

尝试运行小数组的代码然后注意一个模式总是很有用。

算法肯定适用于sup = inf(size = 1)和sup = inf + 1(size = 2);

因此它适用于size = 3,因为您将数组拆分为两个(大小为2和1),并且我们已经确定代码适用于这些较小的大小。

基本上,如果你知道Algo(size = k)和Algo(size = k - 1)返回正确的结果那么Algo(size = 2k = k + k)和Algo(size = 2k - 1 = k)也是如此+(k - 1))。

所以Algo(n)适用于每个n。

这种近乎数学的推理被称为“数学归纳”。

答案 1 :(得分:1)

  • 如果集合中包含一个元素,则返回该元素的答案。不需要重述以进一步简化问题。
  • 如果该集合具有多个元素,请将该集合拆分为一半并递归每一半。

集合中的每个元素最终都会被视为一个元素集合。

答案 2 :(得分:1)

如果我们考虑以下数组

int a[5] = [2, 1, -3, 7, 4];
p(a, 0, 4)

对p的调用分为2个调用m = (0 + 4) / 2 = 2

bool left=p(a,inf,m);来电p(a, 0, 2)

bool right=p(a,m+1, sup);触发p(a, 3, 4)

请注意,相同的数组在后续调用中作为参数传递,只有参数infsup被更改。

由于在infsup这两种情况下仍然不相等,我们称之为计算m

p(a, 0, 2)       |||   p(a, 3, 4)
m = (0+2)/2 = 1  |||   m' = (3+4)/2 = 3

每个分支机构发出2个新电话:

p(a, 0, 1)  ||  p(a, 2, 2)  |||  p(a, 3, 3)  ||  p(a, 4, 4)

infsup相等时,它返回数组中的元素是否严格为正。如果不是,它会继续分裂:

p(a, 0, 0) | p(a, 1, 1) || false ||| true || true
true       | true       || false ||| true || true

最后,结果是对每一个进行布尔运算:

true && true && false && true && true = false

我希望你能遵循这个。

答案 3 :(得分:0)

  

但我看不出那些不在两个极点的元素   数组被认为是......

说服自己的一种方法是使用调试器逐步完成代码。

我不反对gdb,但有时我更喜欢让代码本身报告。

我将报告添加到有趣的地方。

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <cassert>


class T547_t
{
   int depth = 0;

public:

   int exec()
      {
         //          0  1   2  3  4
         int a[5] = {2, 1, -3, 7, 4};

         std::cout << "\n  " << (p(a,0,4) ? "\n  true" : "\n  false") 
                   << "\n" << std::endl;

         // repeat test with all positive values

         int b[5] = {2, 1,  3, 7, 4};

         std::cout << "\n  " << (p(b,0,4) ? "\n  true" : "\n  false")
                   << "\n" << std::endl;

         return 0;
      }


private: // methods

   std::string show(int a[], int inf, int sup)
      {
         std::stringstream ss;
         depth += 1;
         ss << "a[" << inf << "," << sup << "]  "  
            << depth << std::setw(3+depth)<< "  ";
         for (int i = inf; i <= sup; ++i)
            ss << a[i] << " ";
         return ss.str();
      }


   bool p(int a[], int inf, int sup)
      {
         std::cout << "\n  " << show(a, inf, sup) << std::flush;
         if(sup==inf)
         {
            if(a[inf]>0) { depth -= 1; return true;  }
            else         { depth -= 1; return false; }
         }
         int      m = (inf+sup) / 2;
         bool  left = p (a, inf, m);
         bool right = p (a, m+1, sup);
         depth -= 1 ;
         return (left && right);
      }
    // 1 line added to beginning of method p

}; // class T547_t


int main(int , char** )
{
   T547_t   t547;
   return  t547.exec();
}

输出显示:

  a[0,4]  1    2 1 -3 7 4 
  a[0,2]  2     2 1 -3 
  a[0,1]  3      2 1 
  a[0,0]  4       2 
  a[1,1]  4       1 
  a[2,2]  3      -3 
  a[3,4]  2     7 4 
  a[3,3]  3      7 
  a[4,4]  3      4 

  false


  a[0,4]  1    2 1 3 7 4 
  a[0,2]  2     2 1 3 
  a[0,1]  3      2 1 
  a[0,0]  4       2 
  a[1,1]  4       1 
  a[2,2]  3      3 
  a[3,4]  2     7 4 
  a[3,3]  3      7 
  a[4,4]  3      4 

  true

显然,所有的值都会被访问。