我无法理解返回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?
答案 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)
请注意,相同的数组在后续调用中作为参数传递,只有参数inf
和sup
被更改。
由于在inf
和sup
这两种情况下仍然不相等,我们称之为计算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)
当inf
和sup
相等时,它返回数组中的元素是否严格为正。如果不是,它会继续分裂:
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
显然,所有的值都会被访问。