在磁盘上存储列并读取行

时间:2015-06-22 22:31:08

标签: c++ file matrix io

所以我有一个C ++代码,可以找到方形矩阵的逆矩阵。逆是完整的,将它全部保存在内存中是不好的,因为我正在使用数十万列。我的代码逐个生成列。找到反向后,我的其余代码逐个需要行。理想情况下,我想按照以下步骤进行:

重复: 1)找到一列 2)将其存储在磁盘上 3)从内存中删除列。

重复: 1)从磁盘中读取一行 2)处理它(它基本上是线性程序的目标函数) 3)从内存中删除行。

这样做的一种方法是将矩阵写入文件中。意思是,我将第一列写为"实际"在文件中的列,然后我写下它旁边的第二个(效率会低一点),依此类推。如果我没有弄错的话,最后一列将需要写入O(n ^ 2)。这样做可以很容易地读取行。另一种方法是将列写为行,然后稍后读取列。但同样,最后一列将采用O(n ^ 2)来读取。第三种方法是使用n个文件,但打开和关闭n个文件效率很低。

有关如何处理此类问题的任何想法?也许我必须使用数据库(可能是SQL)来为每个条目读取和写入O(1)?

谢谢。

2 个答案:

答案 0 :(得分:1)

如果它是方阵,则很容易编写随机访问文件。例如,如果按行存储矩阵,如...

FILE * f = fopen( FileName, "w+b" );
for(int i = 0; i < MaxRows; ++i) {
    for(int j = 0; j < MaxColumns; ++i) {
        fwrite( &v[ i ][ j ], 1, sizeof( double ), f );
    }
}

现在你可以去任何你想去的地方。只要考虑到每次都必须应用公式:

pos = ( MaxColumns * rowNumber ) + colNumber;

为了将自己定位在文件中,您必须使用fseek(),它以字节为单位,而不是以元素为单位。

假设您要转到第三列的第一个元素。这个职位将是......

int pos = ( MaxColumns * 2 ) + 0;

所以现在你可以找到那个位置:

fseek( f, pos * sizeof( double ), SEEK_SET );

并且,比方说,读取值:

double value;
fread( &value, 1, sizeof( double ), f );

所以我的答案是:一旦你将矩阵保存在磁盘中,你可以无限制地操纵它,而不用担心它占用多少。

不要忘记关闭文件:

fclose( f );

希望这有帮助。

答案 1 :(得分:0)

提及fseek的解决方案很好。然而,对于大型矩阵来说它可能非常慢(因为磁盘不像随机访问,特别是很远)。为了加快速度,你应该使用阻止。

我会展示一个基本概念,如果需要,可以进一步解释。

首先,将矩阵拆分为相同大小的块,如下所示: Split1

块大小的计算方式应使 的列或行能够适合RAM。

接下来,将块列保留在内存中,并在此处复制首先生成的blocksize列。黄色部分是你保留在内存中的颜色,橙色是你下一个生成的列: SplitColumns

完成第一个blocksize列后,将它们转储到单独的文件中(对于我的图像,您可以命名此类文件&#34; A1&#34;,&#34; A7&#34;和& #34; A13&#34;),然后从下一列的块开始。

如果稍后需要此矩阵,请反转此过程。从准备好的文件中读取(例如,&#34; A1&#34;,&#34; E1&#34;,&#34; I1&#34;和&#34; M1&#34;)第一行块,以及逐行处理:

SplitRows