在磁盘上存储列并读取行 < >我有一个C++方程式,它可以找到正方形矩阵的逆。相反的结果是满的,如果把它全部保存在内存中就不好了,因为我正在处理成千上万的列。我的代码逐个生成列。在找到相反的结果后,我的代码的其余部分需要一行一行地执行。理想情况下,我希望进行如下工作:

在磁盘上存储列并读取行 < >我有一个C++方程式,它可以找到正方形矩阵的逆。相反的结果是满的,如果把它全部保存在内存中就不好了,因为我正在处理成千上万的列。我的代码逐个生成列。在找到相反的结果后,我的代码的其余部分需要一行一行地执行。理想情况下,我希望进行如下工作:,c++,file,matrix,io,C++,File,Matrix,Io,重复: 1) 找一列 2) 将其存储在磁盘上 3) 从内存中删除该列 重复: 1) 从磁盘中读取一行 2) 处理它(它基本上是线性规划的目标函数) 3) 从内存中删除该行 一种方法是按原样在文件中写入矩阵。。也就是说,我在文件中将第一列作为“实际”列写入,然后在它旁边写入第二列(这样效率会低一点),依此类推。如果我没弄错的话,最后一列将用O(n^2)来写。这样做可以使读取行非常容易。另一种方法是将列作为行写入,然后稍后读取列。。但是,最后一列需要O(n^2)才能读取。第三种方法是使用n个文件,但

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

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

一种方法是按原样在文件中写入矩阵。。也就是说,我在文件中将第一列作为“实际”列写入,然后在它旁边写入第二列(这样效率会低一点),依此类推。如果我没弄错的话,最后一列将用O(n^2)来写。这样做可以使读取行非常容易。另一种方法是将列作为行写入,然后稍后读取列。。但是,最后一列需要O(n^2)才能读取。第三种方法是使用n个文件,但打开和关闭n个文件效率很低

对如何解决这样的问题有什么想法吗?也许我必须使用数据库(可能是SQL)来实现每个条目的读写O(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 );
    }
}
为了在文件中定位您自己,您必须使用
fseek()
,它以字节而不是元素计数

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

int pos = ( MaxColumns * 2 ) + 0;
因此,现在您可以看到该位置:

fseek( f, pos * sizeof( double ), SEEK_SET );
比如说,读取值:

double value;
fread( &value, 1, sizeof( double ), f );
所以我的答案是:一旦你把矩阵保存在磁盘上,你就可以无限制地操作它,而不用担心它占用了多少空间

只是别忘了关闭文件:

fclose( f );

希望这有帮助。

提到的使用
fseek
的解决方案很好。但是,对于大型矩阵,它可能非常慢(因为磁盘不喜欢随机访问,尤其是在很远的地方)。为了加快速度,你应该使用阻塞

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

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

块大小的计算方式应确保块的列或行可以装入RAM

接下来,将块列保留在内存中,并将首先生成的
blocksize
columns复制到此处。这里黄色部分是您保存在内存中的内容,橙色部分是您下一个生成的列:

完成第一列
blocksize
后,将它们转储到单独的文件中(对于我的图像,您可以将这些文件命名为“A1”、“A7”和“A13”),然后从下一列块开始

当以后需要将此矩阵作为行时,请反转此过程。从准备好的文件(例如,“A1”、“E1”、“I1”和“M1”)读取第一行块,并逐行处理:


您可以在二进制文件中
查找
。哦!令人惊叹的!非常感谢你。我现在就试试。干杯。将矩阵划分为适合内存的块是一个加快速度的好主意,前提是你可以一步一步地应用你的算法,我的意思是在这些块上。恭喜,哦!美好的谢谢。如果矩阵是稀疏的,我只想存储非零元素,会发生什么?因此,我存储的列是稀疏的,因此我稍后将读取稀疏行。
fclose( f );