【问题标题】:If statement not recognizing true conditions?如果语句不承认真实条件?
【发布时间】:2016-11-22 23:01:26
【问题描述】:

我在使用这种二分搜索算法时遇到了问题。以下是变量的解释。

value:数组中被搜索的数字

values[]:正在搜索的数组

n: 数组元素个数

high:正在搜索的数组部分的最高元素(按零索引位置)

low:最低元素(按零索引位置)正在搜索的数组部分

我的问题不是递归。正在搜索的数组部分以“值”为中心,并且正在满足下面确定的条件。问题是我的 if 语句似乎没有认识到它们是。我知道条件得到满足,因为当我为每个递归打印出 values[high]、values[middle] 和 values[low] 时,它表明它们是。

int search(int value, int values[], int n, int high, int low)
 {   
   if (n <= 0)
   {
    return 1;
   }

   int middle = (high + low) / 2;

     ///condition #1
   if (value == values[middle])
   {
     return 0;
   }

   //conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
  else if ( values[middle]==values[low] || values[middle]==values[high])
    {
     return 0;
    }

  else if (value > values[middle])
   {
        low = middle;
        search(value, values, n, high, low);
   }

  else if (value < values[middle])
   {
      high = middle;
      search(value, values, n, high, low);
   }

    return 2;
   } 

这里有什么问题?

【问题讨论】:

  • 我对您的问题进行了非常简短的了解,但通常当我看到这样的问题时,它与stackoverflow.com/questions/9529422/… 有关
  • 您能否扩展您的示例以使其完整并显示不正确的行为?
  • 我认为您应该将middlehighlow 进行比较,而不是values[] 与这些索引...

标签: c binary-search


【解决方案1】:

仔细看这段代码:

else if (value > values[middle])
{
     low = middle;
     search(value, values, n, high, low);
}

else if (value < values[middle])
{
   high = middle;
   search(value, values, n, high, low);
}

请注意,在这些情况下,您会递归调用 search 函数,但您不会对返回值做任何事情。这意味着 search 返回的任何值都将被丢弃,并且代码照常继续,最终返回 2

要解决此问题,请添加以下 return 语句:

else if (value > values[middle])
{
     low = middle;
     return search(value, values, n, high, low);
}

else if (value < values[middle])
{
   high = middle;
   return search(value, values, n, high, low);
}

一般来说,如果您怀疑 if 语句条件没有触发,则值得使用调试器慢慢地逐步完成。这样做可能会导致您注意到 (1) 正确地递归调用函数,但 (2) 返回并丢弃返回的值。

这里的代码可能还有其他问题,但这肯定是您需要解决的问题。

【讨论】:

  • 我认为代码还有多个其他问题,但这是问题之一。
  • 这似乎使它工作......其他问题可能是什么?数组已排序。
【解决方案2】:

Quothcb3k

这似乎使它起作用了......其他问题可能是什么?

这是您的代码,其中包含由templatetypedef 诊断的最小(必要但不充分)fix 和测试工具。

#include <stdio.h>

static
int search(int value, int values[], int n, int high, int low)
{
    if (n <= 0)
    {
        return 1;
    }

    int middle = (high + low) / 2;

    ///condition #1
    if (value == values[middle])
    {
        return 0;
    }

    // conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
    else if (values[middle] == values[low] || values[middle] == values[high])
    {
        return 0;
    }

    else if (value > values[middle])
    {
        low = middle;
        return search(value, values, n, high, low);
    }

    else if (value < values[middle])
    {
        high = middle;
        return search(value, values, n, high, low);
    }

    return 2;
}

int main(void)
{
    int data[15];
    for (int i = 0; i < 15; i++)
        data[i] = 2 * i + 1;

    printf("Data:");
    for (int i = 0; i < 15; i++)
        printf("%3d", data[i]);
    putchar('\n');

    for (int i = -1; i < 2 * 15 + 3; i++)
        printf("Search for %2d - result %d\n", i, search(i, data, 15, 14, 0));
    return 0;
}

这是输出:

Data:  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29
Search for -1 - result 0
Search for  0 - result 0
Search for  1 - result 0
Search for  2 - result 0
Search for  3 - result 0
Search for  4 - result 0
Search for  5 - result 0
Search for  6 - result 0
Search for  7 - result 0
Search for  8 - result 0
Search for  9 - result 0
Search for 10 - result 0
Search for 11 - result 0
Search for 12 - result 0
Search for 13 - result 0
Search for 14 - result 0
Search for 15 - result 0
Search for 16 - result 0
Search for 17 - result 0
Search for 18 - result 0
Search for 19 - result 0
Search for 20 - result 0
Search for 21 - result 0
Search for 22 - result 0
Search for 23 - result 0
Search for 24 - result 0
Search for 25 - result 0
Search for 26 - result 0
Search for 27 - result 0
Search for 28 - result 0
Search for 29 - result 0
Search for 30 - result 0
Search for 31 - result 0
Search for 32 - result 0

无论寻找的值是否存在于数组中,它都会返回 0。这是不正确的行为。

您应该抽出时间学习 Jon Bentley 的 Programming Pearls。它涵盖了各种形式的二进制搜索测试的许多基础知识——显示的测试工具是他所描述的变体。还花时间阅读 Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken。也许你应该放心,随着时间的推移,很多其他人都弄错了二分搜索。 (IIRC,二分搜索的第一个版本是在 1950 年代发布的,但直到 1960 年代初才发布了正确的版本——然后还有 2006 年的额外信息。)

当我在else if (values[middle] == values[low] || values[middle] == values[high]) 之后的块中添加printf() 时,它会打印在每个应该失败的搜索上。请注意,该界面很难发现正在发生的事情——它不报告元素在哪里找到,只是报告是否找到。您可以添加处理残留问题所需的调试和代码更改。 (提示:该条件可能不是解决方案的一部分。但是,当您删除它时,代码会进入永久循环,因为您不会从递归检查的范围中消除已知不在范围内的值.)

这似乎有效——注意return 2; 永远不会被执行(因为最终的else if 永远不会是假的。

#include <stdio.h>

static
int search(int value, int values[], int n, int high, int low)
{
    //if (n <= 0)
    if (n <= 0 || high < low)
    {
        return 1;
    }

    int middle = (high + low) / 2;

    ///condition #1
    if (value == values[middle])
    {
        return 0;
    }

#if 0
    // conditions #2 and #3 (account for the maxes and mins of the array because the operation to find middle truncates)
    else if (values[middle] == values[low] || values[middle] == values[high])
    {
        //printf(" (#2 || #3) ");
        return 0;
    }
#endif

    else if (value > values[middle])
    {
        //low = middle;
        low = middle + 1;
        return search(value, values, n, high, low);
    }

    else if (value < values[middle])
    {
        //high = middle;
        high = middle - 1;
        return search(value, values, n, high, low);
    }

    return 2;
}

int main(void)
{
    int data[15];
    for (int i = 0; i < 15; i++)
        data[i] = 2 * i + 1;

    printf("Data:");
    for (int i = 0; i < 15; i++)
        printf("%3d", data[i]);
    putchar('\n');

    for (int i = -1; i < 2 * 15 + 3; i++)
        printf("Search for %2d - result %d\n", i, search(i, data, 15, 14, 0));
    return 0;
}

输出:

Data:  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29
Search for -1 - result 1
Search for  0 - result 1
Search for  1 - result 0
Search for  2 - result 1
Search for  3 - result 0
Search for  4 - result 1
Search for  5 - result 0
Search for  6 - result 1
Search for  7 - result 0
Search for  8 - result 1
Search for  9 - result 0
Search for 10 - result 1
Search for 11 - result 0
Search for 12 - result 1
Search for 13 - result 0
Search for 14 - result 1
Search for 15 - result 0
Search for 16 - result 1
Search for 17 - result 0
Search for 18 - result 1
Search for 19 - result 0
Search for 20 - result 1
Search for 21 - result 0
Search for 22 - result 1
Search for 23 - result 0
Search for 24 - result 1
Search for 25 - result 0
Search for 26 - result 1
Search for 27 - result 0
Search for 28 - result 1
Search for 29 - result 0
Search for 30 - result 1
Search for 31 - result 1
Search for 32 - result 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多