My task is to sort 1GB file with 100 million numbers using merge sort without recursion. My idea is to split file into 4 pieces, then to 2 and at the end to one file.
#include<iostream>
#include<fstream>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;
std::vector <long> vec;
int i=0,numberOfpieces=0;
string line,filename;
//sorting and merge 2 files
void sort_merge(string result, string file1, string file2){
fstream wynik((result+".txt"), std::ios::out);
string line, line2;
long s1,s2;
fstream sorted_1,sorted_2;
sorted_1.open(file1+".txt");
sorted_2.open(file2+".txt");
getline(sorted_1,line);
s1=atol(line.c_str());
getline(sorted_2,line2);
s2=atol(line2.c_str());
do
{
if(s1==s2)
{
wynik<<s1<<endl;
getline(sorted_1,line);
s1=atol(line.c_str());
getline(sorted_2,line2);
s2=atol(line2.c_str());
}
if(s1<s2)
{
wynik<<s1<<endl;
getline(sorted_1,line);
s1=atol(line.c_str());
}
if(s1>s2)
{
wynik<<s2<<endl;
getline(sorted_2,line2);
s2=atol(line2.c_str());
}
if(sorted_1.eof())
{
do
{
wynik<<s2<<endl;
getline(sorted_2,line2);
s2=atol(line2.c_str());
}
while(!sorted_2.eof());
break;
}
if(sorted_2.eof())
{
do
{
wynik<<s1<<endl;
getline(sorted_1,line);
s1=atol(line.c_str());
}
while(!sorted_1.eof());
}
}
while (!sorted_1.eof() ||!sorted_2.eof());}
int main()
{
fstream file;
file.open("file.txt");
if (file.good() == true )
{
do
{
for(i=1;i<=25000000;i++){ //splittining file into 4 pieces
getline(file,line);
vec.push_back(atol(line.c_str()));
if(file.eof()){ //in case of last piece when quantity of numbers is less than 50
break;
}
}
sort(vec.begin(), vec.end() );//sorting vector
std::string nm = std::to_string(numberOfpieces); //creating indyvidual name for piece
filename="sorted_piece_"+nm+".txt";
fstream sorted_piece(filename, std::ios::out);
for ( auto &i : vec ) { //saving into file
sorted_piece<< i <<endl;
}
numberOfpieces++;
vec.clear();
}
while ( !file.eof() );
}
string outFile;
string sorted1;
string sorted2;
int j=0,counti=0;
for(j=0;j<numberOfpieces;j+=2){//merging into 2 pieces
std::string j1 = std::to_string(j);
std::string j2 = std::to_string(j+1);
std::string c = std::to_string(counti);
outFile=c+"_sorted_piece";
sorted1="sorted_piece_"+j1;
sorted2="sorted_piece_"+j2;
sort_merge(outFile,sorted1,sorted2);
counti++;
}
outFile=numbersSorted;
sorted1=1_sorted_piece;
sorted2=2_sorted_piece;
sort_merge(outFile,sorted1,sorted2);//merging into 1 piece
return 0;
}
Unfortunately it is slow and I don't know exactly what is the best way to improve it, because vector sorting has \$O(nlog(n))\$ complexity. Also, my algorithm with merging 2 files have \$O(n)\$ complexity. Maybe splitting into files takes too much time, but I can't hold vectors that are too long in RAM.
sort
utility to meet your needs? \$\endgroup\$time shuf -r -i 0-2000000000 -n 100000000 > intshuf.txt
took 15s and sorting it withtime sort -n intshuf.txt > intsort.txt
took 107s on a VM on my laptop. This might be a good benchmark to compare your code against. \$\endgroup\$