【问题标题】:Same Binary search not working, one circumstance, but working in another相同的二进制搜索不起作用,一种情况,但在另一种情况下工作
【发布时间】:2016-10-15 19:53:38
【问题描述】:

正在经历 CS50、Pset3 并迫切需要帮助/耐心。 我正在尝试实现helpers.c,以便find.c 具有正确的调用函数..但是它没有连接..

我做了一篇名为testBinSearch 的单独文章,它确实奏效了。使用相同的代码..有人可以告诉我为什么..?

/**
 * helpers.c
 *
 * Computer Science 50
 * Problem Set 3
 *
 * Helper functions for Problem Set 3.
 */
#include <stdio.h>       
#include <cs50.h>

#include "helpers.h"

/**
 * Returns true if value is in array of n values, else false.
 */
//search(needle, haystack, size)
bool search(int value, int values[], int n)

{
    // TODO: implement a Binary searching algorithm (You are welcome to take an iterative approach (as with a loop) or a recursive approach (wherein a function calls itself).)



        //define startPoint. numberOfArrayElements(aka size) - (numberOfArrayElements(aka size) - 1) or Element[0]

       //define endPoint. numberOfArrayElements(aka size)
       int endPoint = n - 1; //element! we -1 because array start from 0th element. last element of array that is 5 elements big will thus be (total number of Elements - 1)th element.

       //define midPoint. numberOfArrayElements(aka size)/2
       int midPoint = endPoint/2; //element!

       //while loop? 
       while(n > 0)
            {   
               //if midPoint == needle, return 0
               if(values[midPoint] == value)
               {
                   return 0;
               }

               //////////(if midPoint is smaller(to the left) or larger(to the right) than needle)
               //ELSE IF midPoint > than needle(look left), keep startPoint, change endPoint element to values[midPoint - 1], define midPoint again.
               else if(values[midPoint] > value)
               {
                   endPoint = midPoint - 1;
                   midPoint = endPoint/2;
                   n = endPoint;
                   printf("mid point is more than needle\n");
               }
               //ELSE midPoint < than needle(look right), keep endPoint, change Startpoint element to values[midPoint + 1], define mindPoint again.
               else if(values[midPoint] < value)
               {
                   int startPoint = midPoint + 1;

                   //define midpoint again
                   midPoint = (endPoint + startPoint)/2;
                   n = endPoint - startPoint + 1;
                   printf("mid point is less than needle\n");
               }


            }



      printf("cued the while loop return 1\n");
      return 1;
}

/**
 * Sorts array of n values. Done with Insertion sort*
 */
void sort(int values[], int n)
{
    //declare variable
    int element;

    //number of iterations (or passes?). Skip first because first array is already sorted
    for (int i = 1; i < n; i++)
        {
            //value of element moving into sorted portion
            element = values[i];

            //declare variable
            int j = 0;

            //index into the unsorted portion
            j = i;

            //iterate sorted portion from right to left while sorted portion is greater than 'Element' being compared in this iteration of i.
            //basically, it stops this loop once the 'Element' is placed to the left of all greater&&sorted numbers.
            while(j > 0 && values[j - 1] > element)
            {
                //shift all sorted positions to the right 
                values[j] = values[j - 1];

                // this enables the loop to move left through the sorted portion
                j = j - 1; 

            }

            //insert temp holder value into the position which is now empty because all sorted&&greater number are to the right of 'Element'
            values[j] = element;

        }


        for(int k = 0; k < n; k++)
         //print to check
            {
                printf("{%i}<-- number in %i-th array (sorted)\n", values[k], k);

            }
}

这里是find.c 代码:

/**
 * find.c
 *
 * Computer Science 50
 * Problem Set 3
 *
 * Prompts user for as many as MAX values until EOF is reached, 
 * then proceeds to search that "haystack" of values for given needle.
 *
 * Usage: ./find needle
 *
 * where needle is the value to find in a haystack of values
 */

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>

#include "helpers.h"

// maximum amount of hay
const int MAX = 65536;

int main(int argc, string argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        printf("Usage: ./find needle\n");
        return -1;
    }

    // remember needle
    int needle = atoi(argv[1]);

    // fill haystack
    int size;
    int haystack[MAX];
    for (size = 0; size < MAX; size++)
    {
        // wait for hay until EOF
        printf("\nhaystack[%i] = ", size);
        int straw = GetInt();
        if (straw == INT_MAX)
        {
            break;
        }

        // add hay to stack
        haystack[size] = straw;
    }
    printf("\n");

    // sort the haystack
    sort(haystack, size);

    // try to find needle in haystack
    if (search(needle, haystack, size))
    {
        printf("\nFound needle in haystack!\n\n");
        return 0;
    }
    else
    {
        printf("\nDidn't find needle in haystack.\n\n");
        return 1;
    }

}

最后,当我将它们全部键入一个文件时,这是单独工作的代码(或至少它似乎工作)......下面标题为testBinSearch

#include <stdio.h>
#include <cs50.h>

void sort(int array[], int NumberOfElements);
bool search(int value, int values[], int n);

int main(void)


{
    //decalre variable
    int NumberOfElements;

    printf("how many Element would you like in this array?\n");
    NumberOfElements = GetInt();

    //declare variable for array
    int array[NumberOfElements];


    for(int i = 0; i < NumberOfElements; i++)
        {
            printf("alright, please key in value of each element\n");
            array[i] = GetInt();
        }

    sort(array, NumberOfElements);

    for (int i = 0; i < NumberOfElements; i++)
        {
            printf("alright, here is your array sorted, element %i is %i\n", i, array[i]);
        }

    printf("value ot search for?\n");
    int value = GetInt();
    search(value, array, NumberOfElements);
}


//----------
void sort(int array[], int NumberOfElements)
{
    //declare variable
    int element;

    //number of iterations (or passes?). Skip first because first array is already sorted
    for (int i = 1; i < NumberOfElements; i++)
        {
            //value of element moving into sorted portion
            element = array[i];

            //declare variable
            int j = 0;

            //index into the unsorted portion
            j = i;

            //iterate sorted portion from right to left while sorted portion is greater than 'Element' being compared in this iteration of i.
            //basically, it stops this loop once the 'Element' is placed to the left of all greater&&sorted numbers.
            while(j > 0 && array[j - 1] > element)
            {
                //shift all sorted positions to the right 
                array[j] = array [j - 1];

                // this enables the loop to move left through the sorted portion
                j = j - 1; 

            }

            //insert temp holder value into the position which is now empty because all sorted&&greater number are to the right of 'Element'
            array[j] = element;

        }

}

//--------------
bool search(int value, int values[], int n)

{
    // TODO: implement a Binary searching algorithm (You are welcome to take an iterative approach (as with a loop) or a recursive approach (wherein a function calls itself).)

    //variables declaration
    //int startPoint;
    //int endPoint;
    //int midPoint;

        //define startPoint. numberOfArrayElements(aka size) - (numberOfArrayElements(aka size) - 1) or Element[0]

       //define endPoint. numberOfArrayElements(aka size)
       int endPoint = n - 1; //element!

       //define midPoint. numberOfArrayElements(aka size)/2
       int midPoint = endPoint/2; //element!

       //while loop? 
       while(n > 0)
            {   
               //if midPoint == needle, return 0
               if(values[midPoint] == value)
               {
                   printf("found it!\n");
                   return 0;
               }

               //////////(if midPoint is smaller(to the left) or larger(to the right) than needle)
               //ELSE IF midPoint > than needle(look left), keep startPoint, change endPoint element to values[midPoint - 1], define midPoint again.
               else if(values[midPoint] > value)
               {
                   endPoint = midPoint - 1;
                   midPoint = endPoint/2;
                   n = endPoint;
               }
               //ELSE midPoint < than needle(look right), keep endPoint, change Startpoint element to values[midPoint + 1], define mindPoint again.
               else if(values[midPoint] < value)
               {
                   int startPoint = midPoint + 1;

                   //define midpoint again
                   midPoint = (endPoint + startPoint)/2;
                   n = endPoint - startPoint + 1;
               }


            }


      printf("could not find it\n");
      return 1;
}

谁能帮助我并告诉我哪里出错了?我想出了代码并直接复制了它,但是一个有效(testBinSearch)而一个无效(helpers.c).. ?

【问题讨论】:

  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建最小、完整和可验证的示例。
  • 请注意,二分搜索函数的酸性测试会创建一个包含 N 个条目的数组(对于不同的 N 值,比如 1 .. 129),并加载一个数组 D,其值为 D[n] = n * 2; for n在 0 .. N-1 (您的排序数据数组)中,然后检查对 -1 .. 2N-1 中的每个值的值 V 的搜索是否正确。对于奇数值,搜索应该失败;对于偶数值,它应该找到正确的值(当然,您的测试可以验证)。我认为你的代码不会通过那种测试。请注意,建议的测试工具不需要用户交互,因此可以完全运行。

标签: c helpers cs50


【解决方案1】:

我不确定这是否涵盖了整个问题,但无论如何......

这个计算

midPoint = endPoint/2;

错了。

假设您有一个包含 100 个元素的数组。该代码可能会导致您查看索引 75 到 99 之间的中点(例如 87),即您已经多次使用 smaller than 路径。

现在,如果您采用 greater than 部分,您会计算出一个超出感兴趣范围的中点(例如 43)

此外,起点变量不是smaller than 情况下的变量。它必须与端点处于同一级别。在每个循环中,您必须更改起点 端点。中点的计算始终取决于起点和终点。

【讨论】:

  • 谢谢!我设法解决了这一切。 @olaf 抱歉,下次我一定会更加小心。感谢大家的大力帮助,真的很喜欢周围有这样一个乐于助人的社区:D
猜你喜欢
  • 1970-01-01
  • 2019-12-12
  • 2020-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-01
  • 2017-08-09
相关资源
最近更新 更多