【问题标题】:Problems with binary search function二分查找功能的问题
【发布时间】:2011-04-28 09:27:34
【问题描述】:

顶部列出的 binary_search 函数有问题。不知道该去哪里。我对二分查找不是很熟悉。

#include <iostream>
#include <cstdlib>
#include <fstream>

using namespace std;

void get_input(ifstream& fin, int a[], int size, int & array_size);

void binary_search (int a[], int & array_size)
{
    cout << "Please enter the element you would like to search for \n";
    int element;
    cin >> element;

    int lastindex=array_size-1, startindex=0;

    while (startindex <= lastindex)
    {
        int midindex=(array_size/2);
        if(element > a[midindex])
        {
            startindex=midindex;
        }
        else if (element < a[midindex])
        {
            lastindex=midindex-1;
        }

    }

}

int main()
{
    int array_size=-1;
    int a[100];

    ifstream fin;

    get_input (fin, a, 100, array_size);

    binary_search (a, array_size);

    return 0;
}

void get_input (ifstream& fin, int a[], int size, int & array_size)
{
    fin.open("numbers.txt");
    if (fin.fail())
    {
        cout << "File failed to open";
        exit(1);
    }


    for(int i = 0; i < size; i++)
    {
        a[i] = 0;
    }

    cout << "The numbers in the array are: \n\n";

    for (int i = 0; i < size; i++)
    {
        if (!fin.eof())
        {
            fin >> a[i];
            array_size ++;
        }
    }

    for (int i = 0; i < array_size; i++)
    {
            cout << a[i] << "  ";
    }

    cout << "\n\n\n";
    cout << "The numbers in the array sorted are: \n\n";

   for(int i = 0; i < array_size; ++i )
   {
        int temp2 = a[i];

        for (int j = i+1; j < array_size; ++j )
        {

            if( a[j] < temp2)
            {
                temp2 = a[j];

                int temp = a[i];
                a[i]    = a[j];
                a[j]    = temp;
            }
        }
    }





    for (int i = 0; i < array_size; i++)
    {
            cout << a[i] << "  ";
    }

    cout << "\n\n\n";

    fin.close();
}

完成后,程序假设从文件中获取输入,将其分配给数组,然后对数组进行排序。在此之后,我需要使用二进制搜索来查找用户给出的数字并将其在数组中的位置显示给用户。

更新:找到的索引输出错误....我应该在 midindex 中添加一个吗?

void binary_search (int a[], int & array_size)
{
    cout << "Please enter the element you would like to search for \n";
    int element;
    cin >> element;

    int lastindex=array_size-1, startindex=0;

    while (startindex <= lastindex)
    {
        int midindex= startindex + (lastindex - startindex) / 2;

        if(element > a[midindex])
        {
            startindex=midindex+1;
        }
        else if (element < a[midindex])
        {
            lastindex=midindex-1;
        }
        else if (element == a[midindex])
        {
            cout<<"Element "<<element<<" found at index "<<midindex<<endl;
            return;
        }



    }

}

【问题讨论】:

  • 该去哪里?首先,您应该将 i/o 与搜索函数分开,并将要搜索的元素作为参数传递给函数。
  • 为什么不使用std::vectorstd::swap等?
  • @GMan 不能,必须手动编码。或者我会。
  • @GMan -- 可能与他不使用 std::binary_search(homework) 的原因相同
  • @Alec:你总是说你得到了错误的索引。您能否向我们展示您的测试数据和程序的输出,以便我们提供帮助而不是猜测?

标签: c++ arrays algorithm search binary-search


【解决方案1】:

尝试改变

startindex=midindex;

到:

startindex=midindex + 1;

int midindex=(array_size/2);

int midindex= startindex + (lastindex - startindex) / 2

最重要的是,当你找到元素时你什么都不做!

if(element == a[midindex]) {
  cout<<"Element "<<element<<" found at index "<<midindex<<endl;
  return;
}

【讨论】:

  • 是的,当我看到你的答案是 startindex=midindex + 1 时,我投了反对票,现在已修复 :)
  • 这很完美,只是我没有找回正确的中间索引。
  • 如果元素存在于数组中,你应该得到正确的索引。您的元素是否存在于数组中?
  • 是的,输出数字是 1、6、7、11、19、21 ......等等。当我搜索 11 时,我没有得到正确的索引。
  • 另请注意,索引从0 开始,而不是1。如果你想要人类风格指数(从 1 开始),你应该在显示其值之前将 1 添加到 midindex
【解决方案2】:

我的第一反应是换行

int midindex=(array_size/2);

int midindex = startindex + (lastindex - startindex) / 2;

另外,您不想报告是否找到了所寻找的元素吗?为了检测找到元素时的情况,另一个if 分支如下

if( element == a[midindex] )

可以插入。里面可以有一个return element;return midindex,在循环外有一个return failure;


编辑:我偶然尝试编写一个二进制搜索版本。我并没有声称它是正确的,因为二进制搜索因不正确而(臭名昭著)。 Some code with test cases and output 已上传至键盘。

片段:

int *
mybsearch( int const *  const a, size_t const n, int const key ) {

    int * lo = const_cast< int * >( a );
    int * hi = lo + n;

    while( lo <= hi ) {

        int * const mid = lo + (hi - lo) / 2;
        int const midelem = *mid;

        if( key == midelem ) {
            return mid;
        }
        else if( key < midelem ) {
            hi = mid - 1;
        }
        else {
            lo = mid + 1;
        }
    }

    return NULL;
}

主要和测试代码:

int main() {

    int const arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
    size_t const num = sizeof( arr ) / sizeof( int );

    int * pos20 = mybsearch( arr, num, 20 );
    assert( pos20 && (*pos20 == 20) );

    int * pos25 = mybsearch( arr, num, 25 );
    assert( !pos25 );

    int * pos5 = mybsearch( arr, num, 5 );
    assert( !pos5 );

    int * pos105 = mybsearch( arr, num, 105 );
    assert( !pos105 );
}

【讨论】:

    【解决方案3】:

    二分搜索可以很好地用作递归算法。传入数组和长度,检查中间值,并酌情在数组的上/下半部分进行递归。

    【讨论】:

      【解决方案4】:

      仔细考虑当array_size = 1 时int midindex=(array_size/2); 的不正确之处。然后推广到array_size = 3。然后推广到任何奇数。这需要您在头脑中或在纸上进行小规模运行模拟。

      【讨论】:

        【解决方案5】:

        你已经接近了。你想做这样的事情:

        int binary_search ...
        

        所以你可以返回元素的索引

        while (startindex < lastindex)    
        {
            int midindex=(startindex+endindex)/2;
            if(element = a[midindex]) {
                return midindex;
            }
            else if(element > a[midindex])
            {
                startindex=midindex+1;
        

        【讨论】:

        • 语句int midindex=(startindex+endindex)/2; 容易受到算术溢出的影响。见googleresearch.blogspot.com/2006/06/… 更好的写法是:int midindex = startindex + (endindex - startindex)/2;
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 2019-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多