我试图保存一个3d数组文件的格式,可以很容易地检索和更新。我找不到一个简单的方法来做这件事。
是一个三维int数组。我更喜欢这样的保存方法:
//save
for (int z1 = 0; z1 <= z; z1++)
{
for (int c = 0; c < m.Length; c++)
{
for (int x = 0; x < 4; x++)
{
writeToFile("matrix.txt", matrix[z1][c][x];
}
}
}
和类似的检索方法,但在这一点上我一点也不挑剔,任何可以保存到文件并且易于检索的内容都可以。
上面的只是首选,因为它允许我只保存数组中保存数据的部分。
数组的大小类似于m[4000][7000][4],但它是稀疏填充的。
编辑:经过长时间的运行,事实证明我的机器不能运行这种大小的数组,所以我将切换到xml数据集。谢谢大家的建议,抱歉我不能更好的执行。
你需要的是工具。
现在这些是我的建议,还有其他的解决方案,可能更适合…
首先到这里熟悉一下这个库。你需要的可能是这个稀疏矩阵数据结构,或者是一个稀疏向量。
第二,如果你不关心文件保存的格式,那么。net有一个很棒的东西,叫做二进制序列化,在这里解释。
现在这一切听起来很复杂,但它几乎沿着这条线:
// create a matrix, Im using a dense one, but you can use a sparse matrix in pretty much the same way
Matrix<double> matrix = DenseMatrix.OfArray(new double[,] {
{1,1,1,1},
{1,2,3,4},
{4,3,2,1}});
var formatter = new BinaryFormatter();
// saving
using(var fileStream1 = File.Create("file.file"))
{
formatter.Serialize(fileStream1, matrix);
}
Matrix<double> newMatrix= null;
// retreving
using(var fileStream2 = File.Open("file.file"))
{
newMatrix = (Matrix<double>)formatter.DeSerialize(fileStream2);
}
性能方面,这对于稀疏矩阵(示例显示了密集矩阵)应该是非常有效的,因为Math。Net使用CSR,所以保存他们的数据…
链接:http://numerics.mathdotnet.com/docs/http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra.Single/SparseMatrix.htmhttp://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra.Single/SparseVector.htmhttp://msdn.microsoft.com/en-us/library/72hyey7b%28v=vs.110%29.aspxhttp://en.wikipedia.org/wiki/Sparse_matrix Compressed_sparse_row_.28CSR_or_CRS.29
您可以使用类似于图论的方法,将图保存为相邻节点的列表,但在您的情况下扩展到3维:仅保存值不同于0的数据。另一方面,您应该使用int [,,] matrix=new int[4000,7000,4]
形式的多个数组,而不是单独索引。您的保存方法可能看起来像这样,考虑到前面的:
for (int z1 = 0; z1 <= z; z1++)
{
for (int c = 0; c < m.Length; c++)
{
for (int x = 0; x < 4; x++)
{
if(matrix[z1,c,x]!=0)
{
File.AppendAllText("matrix.txt",z1+" "+c+" "+x+" "+matrix[z1,c,x]+System.Environment.NewLine)//NewLine to isolate each matrix value on a different line
}
}
}
}
类似地,你的Read方法应该是这样的:
string[] lines=File.ReadAllLines("matrix.txt");
//assuming your matrix is initialized with 0s
foreach(string line in lines)
{
string[] elementsInLine=line.Split(' ');
int z1=int.Parse(elementsInLine[0]);
int c=int.Parse(elementsInLine[1]);
int x=int.Parse(elementsInLine[2]);
matrix[z1,c,x]=int.Parse(elementsInLine[3]);
}
我对你的输出/输入文件的格式做了一些假设,希望它们对你有帮助。
您可以使用Newtonsoft。Json库来序列化您的集合,然后将其写入文件。
http://james.newtonking.com/json你可以使用StreamWriter/StreamReader对文件进行i/o操作
示例:http://james.newtonking.com/json/help/index.html?topic=html/SerializingJSON.htm
考虑到您的数组只是稀疏填充,只写出非零值似乎是最好的方法。
const int DIM0 = 4000;
const int DIM1 = 7000;
const int DIM2 = 4;
int[, ,] array = new int[DIM0 , DIM1 , DIM2 ];
void writeArray(string fileName)
{
StringBuilder SB = new StringBuilder();
for (int k=0; k < DIM2 ; k++)
for (int j=0; j < DIM1 ; j++)
for (int i=0; i < DIM0 ; i++)
{
if (array[i,j,k] != 0)
SB.Append(String.Format("{0},{1},{2},{3}rn",i,j,k,array[i,j,k]) );
}
File.WriteAllText(fileName, SB.ToString().TrimEnd('r').TrimEnd('n') );
}
void readArray(string fileName)
{
string s = File.ReadAllText(fileName).Replace("r","");
string[] p = s.Split('n');
bool error = false;
foreach (string e in p)
{
string[] n = e.Split(',');
int i = 0; int j = 0; int k = 0; int v = 0;
error = !Int32.TryParse(n[0], out i) ;
error &= !Int32.TryParse(n[1], out j);
error &= !Int32.TryParse(n[2], out k);
error &= !Int32.TryParse(n[3], out v);
if (!error) array[i, j, k] = v;
else { /*abort with error message..*/}
}
}
编辑:我已经交换了';'换行,只是在情况下,数组不是很薄填充,所以没有行长度限制可以击中…