2010-10-21 128 views
1

在頂部列出的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; 
     } 



    } 

} 
+2

凡去用它的指數?首先,你應該將I/O從搜索功能中分離出來,並將元素作爲參數傳遞給函數。 – 2010-10-21 03:25:16

+0

爲什麼不使用'std :: vector','std :: swap'等? – GManNickG 2010-10-21 03:29:14

+0

@GMan不得不手動編碼。或者我會。 – Zud 2010-10-21 03:31:50

回答

2

嘗試改變

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; 
} 
+0

是的,當我看到你的答案是'startindex = midindex + 1'時,我投票了,現在修復:) – mcabral 2010-10-21 03:21:45

+0

這工作完美,除非我沒有找回正確的midindex。 – Zud 2010-10-21 03:26:02

+0

如果該元素存在於數組中,則應該得到正確的索引。你的元素是否存在於數組中? – codaddict 2010-10-21 03:30:05

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); 
} 
1

二進制搜索作品很好的遞歸算法。傳入數組和長度,檢查中間值,並根據需要遞歸到數組的上半部分或下半部分。

+0

+1,但看起來更像是一個評論,而不是回答:) – mcabral 2010-10-21 03:18:59

0

當array_size = 1時仔細考慮int midindex=(array_size/2);的不正確之處。然後推廣到array_size = 3.然後將其轉換爲任意奇數。這將需要在您的頭部或紙上進行小型模擬。

0

你很近。你想要做這樣的事情:

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; 
+0

語句int midindex =(startindex + endindex)/ 2;'易受算術溢出的影響。請參閱http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html最好寫下如下內容:int midindex = startindex +(endindex - startindex)/ 2 ;' – Arun 2010-10-21 04:02:26

+0

@ArunSaha好點。謝謝 – 2010-10-21 04:04:27