2017-06-15 35 views
2

我的任務排序是排序,其中的數字排列,每行一個在下面的例子中一個大的文本文件(> 1GB):如何號碼大文本文件

1906885614 
1069046615 
1576929003 
1690826360 
1540261768 
786870227 
1737467783 
295136587 
685162468 

這是我到目前爲止。

#include <iostream> 
#include <map> 
#include <string> 
#include <fstream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

int main() 
{ 
    ios_base::sync_with_stdio(false); 
    ofstream filtered; 
    ofstream filtered1; 
    ifstream textfile ("sort_1.txt"); 
    string text_input; 
    map<string, long int> map_data; 
    vector<string> sort_vec; 
    long int i; 

    if (textfile.is_open()) 
    { 
     filtered.open("filtered_list.txt"); 
     while(! textfile.eof()) 
     { 
      getline (textfile, text_input); 
      map_data[text_input]++; 

      if (map_data[text_input] == 1) 
      { 
       filtered << text_input << '\n'; 
      } 
     } 
     filtered.close(); 
     textfile.close(); 
     cout << "Filter Process Complete!" << endl; 
     map_data.clear(); 
    } 

    else 
     cout << "Unable to Open file: " << endl; 

    ifstream textfile1 ("filtered_list.txt"); 

    if (textfile1.is_open()) 
    { 
     filtered1.open("Filtered_Sorted.txt"); 
     while(! textfile1.eof()) 
     { 
      getline (textfile1, text_input); 
      sort_vec.push_back(text_input); 
     } 
     sort(sort_vec.begin(), sort_vec.end()); 

     for (i = 0; i < sort_vec.size(); i++) 
      filtered1 << sort_vec[i] << endl; 
     cout << "Sorting Process Complete!" << endl; 
     filtered1.close(); 
     textfile1.close(); 
     sort_vec.clear(); 
    } 
    else 
     cout << "Unable to Open file: " << endl; 

    system("pause"); 
    return 0; 
} 

不幸的是,有輸出似乎不正確。這是什麼樣子:

1000107620 
1000112250 
1000112712 
1000113375 
1000115080 
100011777 

和這樣的:

999513319 
999515927 
999526130 
99952947 
999531752 
999533144 
999537 

它看起來像程序忽略最後一位數字,我不知道爲什麼會發生。

+1

Pease正確地縮進代碼。 –

+0

對不起,我只是編輯後:) –

+1

它的排序(以字母數字順序) –

回答

5

您的輸入或輸出沒有任何問題。該程序正在排序string並且不會忽略任何字符或數字。 您獲得的訂購是一個字母數字的訂購號。 逸岸執行它在接下來的輸入:

6 
55 
444 
3333 
22222 
111111 

yelds:

111111 
22222 
3333 
444 
55 
6 

這顯然是字母數字排序。

要解決,你可以

  • 使vector<std::string> sort_vec的問題;一個vector<long long> sort_vec; 。 確保你從文件中讀取行轉換爲long long(或者任何一種你喜歡使用std::stoll功能

像下面的東西應該工作: sort_vec.push_back(std::stoll(text_input));

  • 另一種選擇是使用自定義的比較器,這種情況下唯一的變化就是您撥打sort的方式

單獨使用下面這個技巧:

sort(sort_vec.begin(), sort_vec.end(), 
    [](auto a, auto b){ 
     return stoll(a)<stoll(b); 
}); 

至於建議的@Toby斯佩特是沒有必要的string秒值進行轉換爲數字(一個很好的理由這樣做,是你無法數較長,因爲溢出的那種的long long的最大位數,問題。)。可以簡單地比較叮咬的長度,如果它們相等,則進行字母數字比較(照顧任何前導零)。

sort(sort_vec.begin(), sort_vec.end(),[](auto a, auto b){ 
    return std::make_tuple(a.length(),a) < std::make_tuple(b.length(),b); 
}); 

我修改了代碼,並輸出我得到正確的是:

輸入

6 
55 
444 
3333 
22222 
111111 

輸出

6 
55 
444 
3333 
22222 
111111 

這是你想要的。

+1

像你建議使用'長長'你應該建議使用'stoll()'而不是'stol()' – Stargateur

+0

但是已經是一個雙'l' =) –

+1

你確定'sort_vec.push_back (stol(text_input));'? – Stargateur

1

C++默認按字母順序排序字符串。字符串"1000115080"以字母順序出現在字符串"100011777"之前,因爲字符串中第7個位置的字符'5'按字母順序位於字符'7'之前。這就是「蘋果」一詞在「ax」之前排序的原因,儘管「ax」字符較少。排序這些爲整數,要麼執行排序之前,將字符串轉換爲整數:

std::vector<long int> sort_vec; 
std::string text_input; 

while(!textfile.eof()) { 
    long int val; 
    textfile >> val; 
    // do some error checking here. 
    sort_vec.push_back(val); 
} 

sort(sort_vec.begin(), sort_vec.end()); // now this is in numerical order 

或者通過自定義比較函數std::sort

std::vector<std::string> sort_vec; 
std::string text_input; 

bool comp(std::string a, std::string b) { 
    if (a.size() < b.size()) { // numbers with fewer digits are smaller 
     return true; 
    } 
    if (a.size() > b.size()) { 
     return false; 
    } 
    return a < b; 
} 

while(!textfile.eof()) { 
    std::string val; 
    std::getline(textfile, val); 
    // do some error checking here. 
    sort_vec.push_back(val); 
} 

sort(sort_vec.begin(), sort_vec.end(), comp); // now this is in numerical order, but sort_vec still contains strings rather than ints. 

正如評論所說,你可能會得到如果你自己實現選項2(前導零,負/正符號等),那麼錯誤的答案是,所以更好地堅持讓標準庫爲你轉換爲整數。

+0

你的第二個解決方案將會非常緩慢。 – Stargateur

+0

@ Stargateur,它可能比轉換爲long更快,因爲size()是一個常量操作,並且一旦出現不匹配,char-by-char比較就會停止。然而,當'b.size()