c++ - 如何对大文本文件中的数字进行排序

标签 c++ sorting

我的任务是对一个大文本文件 (>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;
}

不幸的是,have 输出似乎不正确。这是它的样子:

1000107620
1000112250
1000112712
1000113375
1000115080
100011777

还有这样的东西:

999513319
999515927
999526130
99952947
999531752
999533144
999537

程序似乎忽略了最后一位数字,我不知道为什么会这样。

最佳答案

您的输入或输出没有任何问题。程序正在排序string并且不会忽略任何字符或数字。 您获得的顺序是字母数字顺序。 事实上在以下输入上执行它:

6
55
444
3333
22222
111111

产量:

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 Speight 所建议的,无需转换 string s 到数字(这样做的一个很好的理由是,由于溢出问题,您不能对超过 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

这就是你想要的。

关于c++ - 如何对大文本文件中的数字进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44570231/

相关文章:

xml - xsl :sort does not work together with xsl:choose or if

algorithm - 删除多个和大型词典文件中的重复单词

c++ - 在 C++ 中创建类列表

c++ - 模板参数值中的 Lambda 表达式

c++ - atof 改变全局数组的值

java - 不能缩短具有大字符串数字的字符串数组

c# - 如何按字母顺序对字母数字列表进行排序

c++ - 排序多维数组并保持索引 C++

c++ - 从成员函数模板化参数调用成员函数

c++ - 需要 libstdc++.so.6(GLIBCXX_3.4.21)(64bit)(Centos 7 错误)