我的任务是对一个大文本文件(> 1GB)进行排序,其中每行排列一个数字,如下例所示:
1906885614
1069046615
1576929003
1690826360
1540261768
786870227
1737467783
295136587
685162468
Run Code Online (Sandbox Code Playgroud)
这就是我到目前为止所做的.
#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;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,有输出似乎不正确.这就是它的样子:
1000107620
1000112250
1000112712
1000113375
1000115080
100011777
Run Code Online (Sandbox Code Playgroud)
和这样的事情:
999513319
999515927
999526130
99952947
999531752
999533144
999537
Run Code Online (Sandbox Code Playgroud)
看起来该程序忽略了最后的数字,我不知道为什么会发生这种情况.
输入或输出没有任何问题.该程序正在排序string,不会忽略任何字符或数字.
您获得的订单是字母数字.事实上,在以下输入上执行它:
6
55
444
3333
22222
111111
Run Code Online (Sandbox Code Playgroud)
yelds:
111111
22222
3333
444
55
6
Run Code Online (Sandbox Code Playgroud)
这显然是按字母顺序排列的.
要解决问题,你可以
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);
});
Run Code Online (Sandbox Code Playgroud)
正如@Toby Speight所建议的,没有必要将strings 转换为数字(这样做的一个很好的理由是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);
});
Run Code Online (Sandbox Code Playgroud)
我修改了你的代码,我获得的输出是正确的:
6
55
444
3333
22222
111111
Run Code Online (Sandbox Code Playgroud)
6
55
444
3333
22222
111111
Run Code Online (Sandbox Code Playgroud)
这就是你想要的.