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