【问题标题】:Best way to write a 3d int Array to file (and update it)?将 3d int Array 写入文件(并更新它)的最佳方法?
【发布时间】:2014-08-09 19:18:46
【问题描述】:

我正在尝试以易于检索和更新的格式将 3d 数组保存到文件中。我没有找到一个简单的方法来做这件事。

它是一个 3 维的 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 数据集。谢谢大家的建议,对不起,我不能更好地实施它们。

【问题讨论】:

  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 文件格式是否合适?也许,您可能希望将带有 3d 数组的对象序列化为 xml 文件。
  • @Dmitry 不,文件格式无关紧要。您有向 xml 写入和检索数据的方法吗?谢谢
  • 为什么不使用序列化你的对象(3D数组)?
  • 用你的 3d int 创建一个类。类 My3dInt { 公共 int[10][10][10] ;}。将类标记为 [Serializable] 将您的数组保存到此字段并使用 Xml 序列化。查看示例:msdn.microsoft.com/en-US/en-en/library/vstudio/…

标签: c# arrays multidimensional-array writetofile


【解决方案1】:

你需要的是工具。

现在这些是我的建议,还有其他解决方案,也许更适合...

首先去here 熟悉这个库。你需要的可能是this sparse matrix data structure 或者Sparse vector

其次,如果你不关心文件保存的格式,那么.Net有一个奇妙的东西叫做二进制序列化explained here

现在这一切听起来很复杂,但大致如下: //这是在没有 VS 的情况下编写的...

// 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.htm http://numerics.mathdotnet.com/api/MathNet.Numerics.LinearAlgebra.Single/SparseVector.htm http://msdn.microsoft.com/en-us/library/72hyey7b%28v=vs.110%29.aspx http://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_.28CSR_or_CRS.29

【讨论】:

    【解决方案2】:

    您可以使用类似于图论的方法,将图保存为相邻节点的列表,但在您的情况下扩展到 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]);
    }
    

    我对您的输出/输入文件的格式做了一些假设,希望它们对您有所帮助。

    【讨论】:

      【解决方案3】:

      您可以使用 Newtonsoft.Json 库来序列化您的集合,然后将其写入文件。

      http://james.newtonking.com/json

      您可以使用 StreamWriter / StreamReader 对文件进行 i/o 操作

      示例:http://james.newtonking.com/json/help/index.html?topic=html/SerializingJSON.htm

      【讨论】:

        【解决方案4】:

        鉴于您的数组只是稀疏填充,只写出非零值似乎是最好的方法。

            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}\r\n",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..*/}
                }
            }
        

        编辑:我已经交换了 ';'对于换行符,以防万一数组填充得不够细,这样就不会达到行长限制..

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-08
          • 2011-05-16
          • 2011-06-28
          • 1970-01-01
          • 2013-12-08
          • 2020-09-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多