как изменить порядок строк в файле

0

Как мы можем почитать порядок строк в файле, а не сами строки. Файл может стать огромным.

Не следует предполагать длину линии.

Входные данные :

this is line1
this is line2
this is line3

Пример:

this is line3
this is line2
this is line1

Я, хотя и использовал другой файл в качестве буфера, например структуры данных стека, но не мог с ним никуда идти.

Любые мысли по этому поводу?

Теги:
algorithm

3 ответа

3

Читайте в больших блоках файла, начиная с обоих концов. Внутри этих блоков поменяйте первую строку для последней строки, а затем переместите оба указателя, чтобы отслеживать, где вы находитесь. Выпишите каждый блок по мере его заполнения. Когда два указателя встречаются посередине, все готово.

Не пытайтесь модифицировать блоки на месте, что усложнит ситуацию. Используйте четыре блока, первый блок чтения, первый блок записи, последний блок чтения и последний блок записи. Когда каждый блок записи завершен, напишите его. Поскольку каждый блок чтения исчерпан, прочитайте его в другом. Будьте внимательны, чтобы не перезаписывать все, что вы еще не читали!

Это должно быть довольно просто, просто утомительно. Если вам не нужно, чтобы он был оптимальным, вы можете просто читать блоки назад и выписать новый файл, а затем перенести его поверх существующего файла.

1

Если файл не помещается в память, то это двухпроходный процесс. На первом проходе вы читаете фрагменты файла (столько строк, сколько вписывается в память), а затем записывайте их во временный файл в обратном порядке. Так что у тебя есть:

while not end of input
    read chunk of file into array of lines
    write lines from array to temporary file, in reverse order
end while

Когда вы закончите первый проход, у вас будет куча временных файлов: temp1.txt, temp2.txt, temp3.txt... tempN.txt.

Теперь откройте последний файл (tempN.txt) для добавления и начните добавлять файлы в обратном порядке. Так что у тебя есть:

open fileN for append
fileno = N-1
while fileno > 0
    append file_fileno to fileN
    fileno--
end while

Затем переименуйте tempN.txt и удалите другие временные файлы.

Кстати, вы можете использовать утилиту конкатенации, поставляемую операционной системой, для шага 2. В Windows, например, вы можете заменить шаг 2:

copy /A file4.txt+file3.txt+file2.txt+file1.txt mynewfile.txt

На других платформах есть аналогичные утилиты.

Однако вы можете столкнуться с ограничениями длины командной строки.

0

это можно сделать двумя простыми шагами:

шаг 1: отменить все файлы

шаг 2: отменить каждую линию

step:0   1       2
---------------------
abc      zyx     xyz
1234 =>  4321 => 1234 
xyz      cba     abc

EDIT: вот полное решение:

#include <iostream>
#include <fstream>
#include <algorithm>
#define BUFFSIZE 4098 /*make sure this is larger then the longest line...*/
using namespace std;

bool reverse_file(const char* input, const char* output)
{
    streamsize count=0;
    streamoff size=0,pos;
    char buff[BUFFSIZE];

    ifstream fin(input);
    ofstream fout(output);

    if(fin.fail() || fout.fail()){
        return false;
    }

    fin.seekg(0, ios::end);
    size = fin.tellg();
    fin.seekg(0);
    while(!fin.eof()){  
        fin.read(buff, BUFFSIZE);
        count = fin.gcount();
        reverse(buff,buff+count);
        pos = fin.tellg();
        if(pos<0) {
            pos = size;
        }
        fout.seekp(size - pos);
        fout.write(buff,count);
    }
    return true;
}

bool reverse_file_lines(const char* input, const char* output)
{
    streamsize count=0;

    char buff[BUFFSIZE];

    ifstream fin(input);
    ofstream fout(output);

    if(fin.fail() || fout.fail()){
        return false;
    }

    while(!fin.eof()){  
        fin.getline(buff, BUFFSIZE);
    /*if BUFFSIZE is smallest then line size gcount will return 0, 
        but I didn't handle it...*/
        count = fin.gcount();
        if(buff[count-1]==0)count--;
        reverse(buff,buff+count);
        fout.write(buff,count);
        if(!fin.eof()){
            fout<<endl;
        }
    }
    return true;
}


int main()
{
    reverse_file("test.in", "test.tmp");
    reverse_file_lines("test.tmp","test.out");
    return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню