C# 未知维数组的顺序填充

C# 未知维数组的顺序填充,c#,arrays,algorithm,performance,multidimensional-array,C#,Arrays,Algorithm,Performance,Multidimensional Array,我有一个未知维度的数组。例如,它可能是对象[],对象[,],对象[,,] 我希望按顺序填充它(例如,对于[2,2],此顺序为:0,0;0,1,1,0;1,1): 数组arr=…//输入阵列 对于(int i=0;iint[]索引 } 我知道I的对话可以通过%操作符完成,但很难想象一个精确的多维算法。只有两个维度的答案: 我可以在遍历数组时使用Stack来存储索引,但是%似乎效率更高(这里我真的需要关心性能)。但是我不确定Stackvs%这是我相信您正在寻找的算法 public static i

我有一个未知维度的
数组
。例如,它可能是
对象[]
对象[,]
对象[,,]

我希望按顺序填充它(例如,对于[2,2],此顺序为:0,0;0,1,1,0;1,1):

数组arr=…//输入阵列
对于(int i=0;iint[]索引
}
我知道
I
的对话可以通过
%
操作符完成,但很难想象一个精确的多维算法。只有两个维度的答案:


我可以在遍历数组时使用
Stack
来存储索引,但是
%
似乎效率更高(这里我真的需要关心性能)。但是我不确定
Stack
vs
%

这是我相信您正在寻找的算法

public static int[] SingleIndexToMulti(int index, int[] dimentionSizes)
{
    var result = new int[dimentionSizes.Length];
    for (int i = dimentionSizes.Length - 1; i >=0; i--)
    {
        result[i] = index % dimentionSizes[i];
        index = index / dimentionSizes[i];
    }

    return result;
}
你会像这样使用它吗

Array myArray = Whatever();
int[] dimensionSizes = new int[myArray.Rank];
for(int i =0; i < myArray.Rank; i++)
    dimensionsSizes[i] = myArray.GetLength(i);
for (int i = 0; i < arr.Length; i++)
{
    arr.SetValue(stream.ReadNextObject(), SingleIndexToMulti(i, dimensionSizes)); 
}
Array myArray=Whatever();
int[]dimensionSizes=新的int[myArray.Rank];
for(int i=0;i
演示以下代码

for(int i=0; i < (2*3*4) ;i++)
    Console.WriteLine(string.Join(",", SingleIndexToMulti(i, new[] { 2, 3, 4 })));
for(int i=0;i<(2*3*4);i++)
WriteLine(string.Join(“,”,SingleIndexToMulti(i,new[]{2,3,4}));
产生

0,0,0

0,0,1

0,0,2

0,0,3

0,1,0

0,1,1

0,1,2

0,1,3

0,2,0

0,2,1

0,2,2

0,2,3

1,0,0

1,0,1

1,0,2

1,0,3

1,1,0

1,1,1

1,1,2

1,1,3

1,2,0

1,2,1

1,2,2

1,2,3


我为您提供了一个递归解决方案:

void Fill(Array a, Stream stream)
{
    int[] indices = new int[a.Rank]; // c# should initialize this with 0s
    FillRecursive(a, indices, 0, stream)    
}
void FillRecursive(Array a, int[] indices, int rank, Stream stream)
{
    for (int idx = 0; idx < a.GetLength(rank); idx++)
    {
        indices[rank] = idx;
        if (rank == a.Rank - 1)
            a.SetValue(stream.ReadNextObject(), indices);
        else
            FillRecursive(a, indices, rank + 1, stream);
    }
}

请注意,这不仅适用于任意尺寸,也适用于任意和不同长度的单个尺寸。

您想实现什么?是否要从流中读取对象并将其存储在数组中
i
已经检查了数组中所有可能的索引,为什么不使用
arr.SetValue(stream.ReadNextObject(),i)?@AudricdeSchaetzen,仅适用于一维阵列声音,如
开关
/
案例
。为什么数组的维数未知?你是如何从哪里得到它的?@Sinatr这是一个序列化程序库。数组是使用反射创建的。您可以使用递归(因为每个维度都是嵌套循环),检查项是否为可枚举类型(不确定
IEnumerable
是否为最基本类型),如果是,则为此元素递归运行相同的方法。这将适用于锯齿阵列
列表
。但我不确定多维数组怎么办。是的,这是我一直在寻找的算法,所以我接受了。在你们发布这篇文章之前,我甚至无法将它与堆栈方法进行比较,但现在我发现使用堆栈应该更有效,所以我选择了这种方法。
void Fill(Array a, Stream stream)
{
    int[] indices = new int[a.Rank]; // c# should initialize this with 0s
    FillRecursive(a, indices, 0, stream)    
}
void FillRecursive(Array a, int[] indices, int rank, Stream stream)
{
    for (int idx = 0; idx < a.GetLength(rank); idx++)
    {
        indices[rank] = idx;
        if (rank == a.Rank - 1)
            a.SetValue(stream.ReadNextObject(), indices);
        else
            FillRecursive(a, indices, rank + 1, stream);
    }
}
[0,0,0] => 0
[0,0,1] => 1
[0,0,2] => 2
[0,1,0] => 3
[0,1,1] => 4
...
[2,2,0] => 24
[2,2,1] => 25
[2,2,2] => 26