多流迭代器c ++

B. *_*Hel 14 c++ stream istream-iterator

我的程序的目的是打开m行相同长度的文本文件n,逐列读取文件并打印每列.

例如,对于此文本文件

abcd
efgh 
jklm
Run Code Online (Sandbox Code Playgroud)

我想打印

a e j
b f k
c g l
d h m
Run Code Online (Sandbox Code Playgroud)

由于一个行长度可以是200 000 000并且列长度可以超过10000,我无法在矩阵中打开内存中的所有文件.

从理论上讲,我希望有一个程序在空间中使用O(m)并在时间上使用O(m*n).

一开始,我不得不考虑这些解决方案:

  • 如果我看到每列的所有文件,复杂度为O(m*n²),
  • 如果我使用seekg和一组位置并从一个位置跳到另一个位置,则复杂度为O(m n log(n)).

最后一点,对于某些服务器问题,我只需要使用STL.

我的最后一个想法是创建一个文件的迭代器数组,并在每行的开头初始化这些迭代器.之后,要查看下一列,我只需要增加每个迭代器.这是我的代码

ifstream str2;
str2.open ("Input/test.data", ifstream::in);

int nbline = 3;
int nbcolumn = 4;
int x = 0;

istreambuf_iterator<char> istart (str2);
istreambuf_iterator<char> iend ;

istreambuf_iterator<char>* iarray;
iarray = new istreambuf_iterator<char>[nbline];


while (istart != iend){
    if (x % nbcolumn == 0){
        iarray[x/nbcolumn] = istart;
    }
    istart++;
    x++;
}

for (int j = 0; j<nbcolumn;j++){
    for (int i = 0; i<nbline;i++){
        cout  << *iarray[i] << "\t";
        iarray[i]++;
    }
    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

可悲的是,它不起作用,我把这个东西作为输出

a       e       f       
?       ?       ?       
?       ?       ?       
?       ?       ?       
Run Code Online (Sandbox Code Playgroud)

我认为问题是迭代器数组iarray不是独立于istart,我怎么能这样做?

120*_*arm 6

您可以将任务分解为块,然后处理每个块,然后再转到下一个块.

你需要为每一行提供一个缓冲区(性能越大,性能越好)和该行的搜索位置.您可能还需要通过文件进行初始传递以获得每行的正确偏移量.

将每个行的B字节读入缓冲区(tellg用于保存每行中的位置),然后循环遍历这些字节并生成输出.返回并从每行读取下一个B字节(使用seekg预先设置文件位置,然后tellg记住它)并生成输出.重复直到你完成,小心最后一个块(或小输入)不要越过线的末尾.

使用您的示例,您有3行可以跟踪.使用2的B规格,你会读ab,efjk到您的3个缓冲区.循环你输出的那些aejbfk.回去读下一大块:cd,gh,和lm.这使得cgldhm作为输出.


Mar*_*k R 5

我会这样做:

  1. 打开源文件.
  2. 测量线尺寸
  3. 测量行数(文件大小/(行大小+ EOL大小)).注意EOL可以是2个字节.
  4. 计算结果文件大小.打开结果文件并强制它具有所需的大小,以便稍后您可以搜索文件的任何部分.
  5. 峰值某个大小的正方形,可以记忆.例如1024x1024
  6. 现在你应该加载矩阵的方形部分.用于1024个组成行的行的1024个元素.
  7. 转置广场
  8. 通过寻找正在编写的行的每个部分的正确列,将其写入目标文件.(您可以通过转置一列然后将其写为一行来减少前一点的内存消耗,而不是一次性转置整个方块)
  9. 在整个文件矩阵上迭代正方形

IMO你不能做得更好.最关键的将是如何选择正方形的大小.建议使用2的大功率.