0

我们如何才能尊重文件中的行顺序而不是行本身。文件可能会变得很大。

不应假设线的长度。

输入:

this is line1
this is line2
this is line3

示例输出:

this is line3
this is line2
this is line1

我虽然使用另一个文件作为缓冲区,例如堆栈数据结构,但实际上无法使用它。

对此有什么想法吗?

4

3 回答 3

3

从两端开始读入文件的大块。在这些块内,将第一行换成最后一行,然后移动两个指针以跟踪您所在的位置。填写时写下每个块。当两个指针在中间相遇时,你就完成了。

不要试图修改块,这会使事情变得更复杂。使用四个块,第一个读取块、第一个写入块、最后一个读取块和最后一个写入块。当每个写入块完成时,将其写出。当每个读取块用尽时,读取另一个块。请注意不要覆盖您尚未阅读的任何内容!

它应该相当简单,只是乏味。如果您不需要它是最佳的,您可以向后读取块并写出一个新文件,然后将其移动到现有文件的顶部。

于 2013-10-21T21:20:58.380 回答
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

其他平台上有类似的实用程序。

不过,您可能会遇到命令行长度限制。

于 2013-10-21T22:18:30.923 回答
0

它可以通过两个简单的步骤完成:

第1步:反转所有文件

第2步:反转每一行

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

编辑:这是一个完整的解决方案:

#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;
}
于 2013-10-22T15:41:23.457 回答