【问题标题】:Boolean recursive function always returns true布尔递归函数始终返回 true
【发布时间】:2018-08-02 22:12:18
【问题描述】:

我正在使用递归进行作业。我似乎无法弄清楚为什么当数字不在数组中时我的函数不会返回 false。出于某种原因,在我看来,正在搜索的数字正在被添加到数组中。如果有人能告诉我哪里出错了,将不胜感激。

#include "stdafx.h"
#include <iostream>

using namespace std;

bool isMember(int[], const int, int);

int main() {

    const int SIZE = 5;
    int myArr[SIZE];
    int numSearched;

    cout << "Enter 5 numbers to be searched through." << endl;

    for (int i = 0; i < SIZE; i++) {
        cout << "Enter number " << i + 1 << endl;
        cin >> myArr[i];
    }

    cout << "What number do you want to find?" << endl;
    cin >> numSearched;

    if (isMember(myArr, SIZE, numSearched)) {
        cout << "True" << endl;
    }
    else {
        cout << "False" << endl;
    }

    return 0;
}

bool isMember(int arr[], const int S, int search) {
    bool found = false;

    cout << arr[S] << endl;

    if (arr[S] == search) {

        found = true;
        return found;
    }
    else if ((arr[S] == 0) && (arr[0] != search)) {

        return found;
    }
    else {

        return isMember(arr, S - 1, search);
    }
}

【问题讨论】:

  • else if ((arr[S] == 0) ... 应该是else if ( (S == 0) ...??到目前为止,您正在查看数组的值,而不是索引。
  • 听起来您可能需要学习如何使用调试器来单步调试您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。延伸阅读:How to debug small programs
  • S 是大小,arr[S] 超出边界。
  • arr[S] 访问越界数据,因为S 是数组的大小,最后一个索引是S - 1
  • found 变量的意义何在?为什么不return true;return false;。保持简单!

标签: c++ recursion boolean


【解决方案1】:

许多人指出,您在尝试访问超出数组大小的内存时遇到了内存访问问题。已经在函数的顶级调用中,您会导致问题,因为您将SIZE 作为数组索引参数传递。如果SIZE 是数组的大小,那么arr[SIZE-1] 是内存中数组的最后一个元素。 arr[SIZE] 是结束后的一个元素。访问超出数组内存占用的内存会导致未定义的行为,这很糟糕。

总的来说,糟糕的索引在这里是一个大问题。但是,即使您解决了上述问题,另一个问题行也在这里,因为您试图在 S 命中 0 时停止但您写错了。

else if ((arr[S] == 0) && (arr[0] != search)) {

你希望这样:

else if (S == 0) {

语句arr[0] != search 是多余的,因为上面的条件已经检查过了。原始语句arr[S] == 0 试图将S 处的arr 的值与0 进行比较,而不是测试您的索引变量现在是否为0,我建议的代码就是这样做的。

但这也可能解释了为什么函数总是返回 true,尽管存在未定义的行为并且程序没有崩溃。因为你的函数没有正确终止,它会不断地调用isMember(...,S-1,...)。因此,它将不断减少索引并更改访问的arr[S] 的内存位置。此过程将继续进行,直到找到 arr[S] == 0 或找到您正在寻找的值。碰巧的是,您在内存中某处遇到了目标值,然后又遇到了 0。

【讨论】:

    【解决方案2】:

    您向 isMember 发送从零开始的索引号,当您向 is 成员发送 5 时,未定义 arr[5]。 并且应该使用像

    这样的方法
    isMember(myArr, SIZE - 1, numSearched)
    

    而且您的代码没有结束条件我在您的代码中添加结束条件以在S &lt; 0 之后结束递归

    if (S < 0)
        return false;
    

    试试这个;)

    #include <iostream>
    
    using namespace std;
    
    bool isMember(int[], const int, int);
    
    int main() {
    
        const int SIZE = 5;
        int myArr[SIZE];
        int numSearched;
    
        cout << "Enter 5 numbers to be searched through." << endl;
    
        for (int i = 0; i < SIZE; i++) {
            cout << "Enter number " << i + 1 << endl;
            cin >> myArr[i];
        }
    
        cout << "What number do you want to find?" << endl;
        cin >> numSearched;
    
        if (isMember(myArr, SIZE - 1, numSearched)) {
            cout << "True" << endl;
        }
        else {
            cout << "False" << endl;
        }
    
        return 0;
    }
    
    bool isMember(int arr[], const int S, int search) {
        if (S < 0)
            return false;
        bool found = false;
    
        //cout << "index is " << S << "\t" <<  arr[S] << endl;
    
        if (arr[S] == search) {
    
            found = true;
            return found;
        }
    
        return isMember(arr, S - 1, search); 
    }
    

    【讨论】:

      【解决方案3】:

      错误在于递归函数的停止条件:

      else if ((arr[S] == 0) && (arr[0] != search)) {
      
          return found;
      }
      

      您没有检查索引是否为第一个,而是检查内容是否为零。你可以试试这样:

      else if (S <= 0) {
      
          return false;
      }
      

      您也不需要检查值以匹配“搜索”,因为它与之前的条件是多余的。也可以直接返回false。

      【讨论】:

      • 我还建议采用更具防御性的方法,例如你没有检查负索引。
      • 会以之前的状态返回:
      • 谢谢,我知道我在看一些简单的东西。我倾向于过度思考问题。
      • 最严重的头痛往往是非常简单的事情。复杂性在于找出它们的位置:)
      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 2019-03-25
      • 2015-02-08
      相关资源
      最近更新 更多