2014-03-24 55 views
0

所以問題是我正在採取一個示例文件輸入要求的用戶帳號。現在,輸出爲:錯誤的排序和/或搜索通過外部文件填充的陣列

What is the filename of account numbers? sample.txt 
What is the account number you are looking for? 5552012 
-858993460 
4520125 
5658845 
7895122 
8451277 
1302850 
8080152 
4562555 
5552012 
5050552 
7825877 
1250255 
1005231 
6545231 
3852085 
7576651 
7881200 
4581002 
The account number you were looking for is: 1 
Press any key to continue . . . 

下面輸出的數字:「什麼是帳號?」出於調試目的而歸因於'for'循環。輸出的問題也是頂部數字(-858993460)不是sample.txt文件中存在的數字。應該在那裏的數字是5658845。我猜負數是可能的最小的int,但是。

這部分是我正在使用的代碼。看起來像氣泡排序算法是不正確的。但是,按照指示,我們要按照我所做的書的例子。我已經多次檢查算法函數,發現沒有錯誤,但是我的評估可能是錯誤的。這個問題導致了一個更大的問題,它阻止了在排序數組中找到正確的賬號,而在當前狀態下它返回1,這不是一個存在的數字。

#include <stdafx.h> 
#include <stdio.h> 
#include <fstream> 
#include <string> 
#include <algorithm> 
#include <iostream> 
using namespace std; 

//prototypes 
void sortAcctNums(int accounts[], int arraySize); 
bool findAcctNum(int accounts[], int numElems, int accountNumSearched); 


//main part of the program. This is where all the magic happens 
int main(){ 
    string fileName; 
    int accountNumSearched, count = 0; 
    const int arraySize = 18; 
    int accounts[arraySize]; 
    int location; 

    fstream inputFile(fileName, ios::in); 
    cout << "What is the filename of account numbers? "; 
    cin >> fileName; 

    inputFile.open(fileName); 

    if (inputFile.is_open()){//makes sure the file is able to be read, if not then requests user to try again 
     cout << "What is the account number you are looking for? "; 
     cin >> accountNumSearched; 
     while (inputFile >> accounts[count]){ 
      count++;//populates the array 
     } 
     inputFile.close();//closes the file stream 

     sortAcctNums(accounts, arraySize);//sorts the account numbers 
     location = findAcctNum(accounts, arraySize, accountNumSearched);//assigns the value of the fundAcctNum function to location 
     if (location == -1){ 
      cout << "The account number could not be found" << endl; 
      exit; 
     } 
     else 
      cout << "The account number you were looking for is: " << location << endl; 
    } 
    else 
     cout << "Error opening file. Please try again. " << endl; 

    return 0; 
} 

//this function sorts the account numbers with a bubble sort algorithm 
void sortAcctNums(int accounts[], int arraySize){ 

    bool swap; 
    int temp; 

    do{ 
     swap = false; 
     for (int i = 0; i < (arraySize - 1); i++){ 
      if (accounts[i] > accounts[arraySize + 1]){ 
       temp = accounts[i]; 
       accounts[i] = accounts[arraySize + 1]; 
       accounts[arraySize + 1] = temp; 
       swap = true; 
      } 
     } 
    } while (swap); 
    //this loop is only for testing purposes and should be removed during final build 
    for (int i = 0; i < arraySize; i++){ 
     cout << accounts[i] << endl; 

    } 
} 

//This function searches the sorted array for the specified account number with a Binary sort algorithm 
bool findAcctNum(int accounts[], int numElems, int accountNumSearched){ 

    int first = 0, 
     last = numElems - 1, 
     middle, 
     position = -1; 
    bool found = false; 

    while (!found && first <= last){ 
     middle = (first + last)/2; 
     if (accounts[middle] == accountNumSearched){ 
      found = true; 
      position = middle; 
     } 
     else if (accounts[middle] > accountNumSearched) 
      last = middle - 1; 
     else 
      first = middle + 1; 
    } 
    return position; 
}//end search 
+2

如果你沒有注意到,你冒泡排序不遞減氣泡與每個迭代點(應該)。比較已經冒泡到右側的東西是沒有意義的,因爲它已經擊敗了陣列中的所有其他東西。 'sortAcctNums(accounts,arraySize)'應該使用'count'作爲第二個參數,因爲這是您實際*讀取的任何條目*。 – WhozCraig

+0

我明白你說的有點。使用count是比arraySize更好的選擇。但是當你說泡沫不會減少泡沫指向每一次迭代時,我並不明白。你的意思是說我不斷縮放和排序到正確的位置? – koodeta

+1

[**請參閱正在運行的'bubblesort()'**](http://ideone.com/XisXKL)請特別注意最高端(已排序項目駐留的地方)是如何不斷減少*的。 – WhozCraig

回答

1

正確的程序是:

#include <stdafx.h> 
#include <stdio.h> 
#include <fstream> 
#include <string> 
#include <algorithm> 
#include <iostream> 
using namespace std; 

//prototypes 
void sortAcctNums(int accounts[], size_t count); 
int findAcctNum(int accounts[], int numElems, int accountNumSearched); 


//main part of the program. This is where all the magic happens 
int main(){ 
    string fileName; 
    int accountNumSearched, count = 0; 
    const int arraySize = 18; 
    int accounts[arraySize]; 
    int location; 

    fstream inputFile(fileName, ios::in); 
    cout << "What is the filename of account numbers? "; 
    cin >> fileName; 

    inputFile.open(fileName); 

    if (inputFile.is_open()){//makes sure the file is able to be read, if not then requests user to try again 
     cout << "What is the account number you are looking for? "; 
     cin >> accountNumSearched; 
     while (inputFile >> accounts[count]){ 
      count++;//populates the array 
     } 
     inputFile.close();//closes the file stream 

     sortAcctNums(accounts, sizeof(accounts)/sizeof(*accounts));//sorts the account numbers 
     location = findAcctNum(accounts, count, accountNumSearched);//assigns the value of the fundAcctNum function to location 



     if (location == -1){ 
      cout << "The account number could not be found" << endl; 
      exit; 
     } 
     else 
      cout << "The account number you were looking for is: " << accounts[location] << endl 
    } 
    else 
     cout << "Error opening file. Please try again. " << endl; 

    return 0; 
} 

//this function sorts the account numbers with a bubble sort algorithm 
void sortAcctNums(int accounts[], size_t count){ 

    bool swap = true; 
    int temp; 

    while (count-- && swap){ 
     swap = false; 
     for (size_t i = 0; i < count; ++i){ 
      if (accounts[i] > accounts[i + 1]){ 
       std::iter_swap(accounts + i, accounts + i + 1); 
       swap = true; 
      } 
     } 
    } 
} 

//This function searches the sorted array for the specified account number with a Binary search algorithm 
int findAcctNum(int accounts[], int numElems, int accountNumSearched){ 

    int first = 0, 
     last = numElems - 1, 
     middle, 
     position = -1; 
    bool found = false; 

    while (!found && first <= last){ 
     middle = (first + last)/2; 
     if (accounts[middle] == accountNumSearched){ 
      found = true; 
      position = middle; 
     } 
     else if (accounts[middle] > accountNumSearched) 
      last = middle - 1; 
     else 
      first = middle + 1; 
    } 
    return position; 
}//end search 
+1

+1。如果你想知道爲什麼bubblesort使用整個'while(count-...)'方法而不是'for(i = 0; i <(count-1)...'方法,一個堅定的信徒,除非你真的知道你在做什麼數組下標應該是* unsigned *(比如'size_t')現在想想如果你打開一個* empty *文件進行排序會發生什麼瘋狂。 -1)'當'count'成爲無符號值時* zero *(0)?是啊,不好。下溢。Ouch。希望有道理。 – WhozCraig

+0

這樣做有道理。謝謝!雖然你應該總是使用無符號數組下標中的變量? – koodeta

+1

如果您正在編寫代碼的兩面(調用者和被調用者),我強烈建議使用負面下標的時間非常少,甚至不值得提及。 – WhozCraig

2

你的氣泡排序並不完全正確。你有:

do{ 
    swap = false; 
    for (int i = 0; i < (arraySize - 1); i++){ 
     if (accounts[i] > accounts[arraySize + 1]){ 
      temp = accounts[i]; 
      accounts[i] = accounts[arraySize + 1]; 
      accounts[arraySize + 1] = temp; 
      swap = true; 
     } 
    } 
} while (swap); 

這不是泡沫排序。您需要嵌套for循環進行氣泡排序。回到你的例子,並確保你正在實現它。一個典型的冒泡排序將類似於這樣的:

swap = true; 
for (int i = 0; i < (arraySize - 1) && swap; ++i) 
{ 
    swap = false; 
    for (int j = 0; j < (arraySize - i - 1); ++j) 
    { 
     if (array[j] > array[j+1]) 
     { 
      temp = array[j]; 
      array[j] = array[j+1]; 
      array[j+1] = temp; 
      swap = true; 
     } 
    } 
} 

你得到你的數組中的虛假數字的原因是因爲你與accounts[arraySize+1]比較當前項目(accounts[i])。在這種情況下,您正在比較accounts[20]。由於數組中只有18個項目,因此您正在比較存儲在數組末尾的內存中的一些隨機值。負數不是可能的最小int。

+2

嗯。 *那*不是冒泡排序。冒泡排序通過使用相鄰元素比較將一個值冒泡到不斷下降的終點,在減少終點後重新開始並在任何單遍中不發生交換時完全停止。每次通過時,您的內循環應該在* top *端不斷縮短。出於某種原因,你有*底*收縮*上*,而不是頂部收縮*下*,這是錯誤的。正如所寫,這將不會正確排序。一個簡單的{3,2,1}列表與你的算法完成{2,1,3},這是*不*排序。 – WhozCraig

+0

@WhozCraig:你的評估是正確的。我測試過了,結果不正確。這些價值觀似乎遵循你在一定程度上描述的相同模式。 – koodeta

+0

@WhozCraig:你說得對。我混淆了我的選擇和冒泡排序。固定。謝謝。 –

0

冒泡排序應該是這樣的:

for (int i = 0 ; i < (arraySize - 1); i++) { 
    for (int j = 0 ; j < arraySize - i - 1; j++) { 
     if (array[j] > array[j+1]) { 
      int swap = array[j]; 
      array[j] = array[j+1]; 
      array[j+1] = swap; 
     } 
    } 
} 

試一下,看看你是否仍然得到不好的結果。