История изменений
Исправление
wota,
(текущая версия)
:
~$ cat 1.cpp
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <vector>
#define BUF_SIZE 65536
FILE* in;
const char* getline( uint32_t pos, char* buf )
{
fseek( in, pos, SEEK_SET );
return fgets( buf, BUF_SIZE, in );
}
int main( int argc, char** argv )
{
in = fopen( argv[ 1 ], "rb" );
char buf0[ BUF_SIZE ];
char buf1[ BUF_SIZE ];
uint32_t offset = 0;
std::vector<uint32_t> lines;
char buf[ BUF_SIZE ];
while( fgets( buf, BUF_SIZE, in ) )
{
uint32_t new_offset = ftell( in );
auto pos = std::lower_bound(
lines.begin(), lines.end(), offset,
[&]( uint32_t a, uint32_t b ) { int c = strcmp( getline( a, buf0 ), getline( b, buf1 ) ); return c ? c < 0 : a < b; } );
lines.insert( pos, offset );
fseek( in, offset = new_offset, SEEK_SET );
}
FILE* out = fopen( argv[ 2 ], "wt" );
for( uint32_t pos : lines )
{
getline( pos, buf0 );
fwrite( buf0, strlen( buf0 ), 1, out );
}
fclose( out );
}
~$ g++ -std=c++11 -Ofast 1.cpp && time ./a.out big.txt out.txt
real 0m1.857s
user 0m0.692s
sys 0m1.164s
~$ du -h big.txt
6,2M big.txt
~$ du -h out.txt
6,2M out.txt
~$ wc -l out.txt
128457 out.txt
~$ wc -l big.txt
128457 big.txt
и что забавно - проигрывает самому тупому решению в лоб, хотя понятно, что на больших размерах вставка станет гораздо дороже
П.С. хотя проигрывает наверняка из-за мусора в конце выхлопа
Исходная версия
wota,
:
~$ cat 1.cpp
#include <algorithm>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <vector>
#define BUF_SIZE 65536
FILE* in;
const char* getline( uint32_t pos, char* buf )
{
fseek( in, pos, SEEK_SET );
return fgets( buf, BUF_SIZE, in );
}
int main( int argc, char** argv )
{
in = fopen( argv[ 1 ], "rb" );
char buf0[ BUF_SIZE ];
char buf1[ BUF_SIZE ];
uint32_t offset = 0;
std::vector<uint32_t> lines;
char buf[ BUF_SIZE ];
while( fgets( buf, BUF_SIZE, in ) )
{
uint32_t new_offset = ftell( in );
auto pos = std::lower_bound(
lines.begin(), lines.end(), offset,
[&]( uint32_t a, uint32_t b ) { int c = strcmp( getline( a, buf0 ), getline( b, buf1 ) ); return c ? c < 0 : a < b; } );
lines.insert( pos, offset );
fseek( in, offset = new_offset, SEEK_SET );
}
FILE* out = fopen( argv[ 2 ], "wt" );
for( uint32_t pos : lines )
{
getline( pos, buf0 );
fwrite( buf0, strlen( buf0 ), 1, out );
}
fclose( out );
}
~$ g++ -std=c++11 -Ofast 1.cpp && time ./a.out big.txt out.txt
real 0m1.857s
user 0m0.692s
sys 0m1.164s
~$ du -h big.txt
6,2M big.txt
~$ du -h out.txt
6,2M out.txt
~$ wc -l out.txt
128457 out.txt
~$ wc -l big.txt
128457 big.txt
и что забавно - проигрывает самому тупому решению в лоб, хотя понятно, что на больших размерах вставка станет гораздо дороже