我在cs50课期间遇到问题,我必须编写二进制搜索功能。
尝试运行代码时,会显示以下消息:control may reach end of non-void function
。我尝试通过添加最后一行return false
进行修复,但这会使输出始终为false
。请给我一些提示。
这是我的代码:
bool search_r(int value, int values[], int l, int r) {
int v = values[(l + r) / 2];
int right = r;
int left = l;
if ((l + r) / 2 > 0) {
if (v == value) {
return true;
} else
if (v > value) {
right = ((l + r) / 2);
search_r(value, values, left, right);
} else
if (v < value) {
left = ((l + r) / 2);
search_r(value, values, left, right);
}
} else {
return false;
}
}
答案 0 :(得分:2)
您的功能有几个问题:
search_r()
。此错误导致警告,因为函数在嵌套的return
语句后没有if
语句。最后使return false;
不正确,因为如果找到true
,递归调用应返回value
。(l + r) / 2
或l
非常大,r
可能会溢出。在这种情况下,结果将是不正确的。计算中间索引的正确方法是l + (r - l) / 2
。(l + r) / 2 > 0
,它仅测试中间索引是否为> 0
。而是使用l < r
,即。如果范围不为空,则会包含l
并排除r
。if (v < value)
是多余的,您已针对v == value
和v > value
进行了测试。l
作为变量名有点令人困惑,因为它在视觉上与1
非常相似,特别是对于用于代码的固定间距字体。以下是更正后的版本:
bool search_r(int value, int values[], int left, int right) {
if (left < right) {
int middle = left + (right - left) / 2;
int v = values[middle];
if (v == value) {
return true;
} else
if (v > value) {
return search_r(value, values, left, middle);
} else {
return search_r(value, values, middle + 1, right);
}
} else {
return false;
}
}
最后,该函数可以实现为循环而不是使用递归。编译器可能生成相同的代码,因为递归是终端的,但有些人发现一种方式比另一种方式更直观:
bool search_r(int value, int values[], int left, int right) {
while (left < right) {
int middle = left + (right - left) / 2;
int v = values[middle];
if (v == value) {
return true;
} else
if (v > value) {
right = middle;
} else {
left = middle + 1;
}
}
return false;
}
在这两种情况下,都应该以这种方式调用函数,其中length
是array
的元素数。
bool found = search_r(value, array, 0, length);
答案 1 :(得分:0)
最后else
不是必需的,如果您只是返回false
,它将完全按照您的意愿行事。但是你应该在true
分支内返回if
。或者让函数完全不返回,因为你还没有使用返回值,如果它总是false
,那么它无论如何都不是很有用。
答案 2 :(得分:0)
你的职能:
bool search_r(int value, int values[], int left, int right)
表示将返回 bool 。我认为@chqrlie对此有很好的回应。
如果不满足任何循环或条件,您应该返回一些默认值。