【问题标题】:Assign 1D array values to multidimensional array, of unknown dimensions / type将一维数组值分配给未知维度/类型的多维数组
【发布时间】:2019-11-11 14:40:45
【问题描述】:

我有一个 N 维数组,我希望能够为其分配任何原始值。 (单个数组的一种类型,但所有原始类型的 alg 必须是通用的)。

我写了一个方法可以做到这一点:

var element = Array.CreateInstance(dataType, dataDims);

foreach (var index in GetIndexes(dataDims))
{
     element.SetValue(SomeKindOfValue, index);
}

GetIndexes 函数为给定维度生成所有可能的索引:

     public static IEnumerable<int[]> GetIndexes(int[] dims)
     {
        int lastIndex = dims.Length - 1;
        int lastDim = dims[lastIndex];
        int[] Index = new int[dims.Length];
        int currentDim = lastIndex;

        while (currentDim >= 0) 
        {
            if (currentDim == lastIndex)
            {
                for (int i = 0; i < lastDim; i++)
                {
                    yield return Index;
                    Index[currentDim]++;
                }

                Index[currentDim] = 0;
                currentDim--;
                continue;
            }
            else
            {
                if (Index[currentDim] == dims[currentDim] - 1)
                {
                    Index[currentDim] = 0;
                    currentDim--;
                    continue;
                }
                else
                {
                    Index[currentDim]++;
                    currentDim = lastIndex;
                    continue;
                }
            }
        }
    }

示例:对于 GetIndexes(new int[] {4,2,3}),输出将是:

0, 0, 0 |
0, 0, 1 |
0, 0, 2 | 
0, 1, 0 | 
0, 1, 1 |
0, 1, 2 | 
1, 0, 0 | 
1, 0, 1 | 
1, 0, 2 | 
1, 1, 0 | 
1, 1, 1 | 
1, 1, 2 | 
2, 0, 0 | 
2, 0, 1 | 
2, 0, 2 | 
2, 1, 0 | 
2, 1, 1 | 
2, 1, 2 | 
3, 0, 0 | 
3, 0, 1 | 
3, 0, 2 | 
3, 1, 0 | 
3, 1, 1 | 
3, 1, 2 |

问题是,以这种方式分配值非常耗时,而且这种算法需要尽可能高效。

我在想多维数组实际上是内存中的一维数组,所以如果我可以访问每个元素的指针,那么我可以直接分配没有任何计算的值。问题是我无法找到一种方法来创建指向泛型类数组(或其第一个元素)的指针。

基本上,我正在尝试编写一个通用函数(它将接受任何原始类型作为数组的数据类型,并且将接受任何多维数组):

public static unsafe void SetElementsByPointer(int[,] array, int[] values)
{
            if (values.Length != array.LongLength)
                 throw new Exception("array and values length mismatch.");

            fixed (int* pStart = array)
            {
                for (int i = 0; i < array.LongLength; i++)
                {
                    int* pElement = pStart + i;
                    *pElement = values[i];
                }
            }
        }

我会欣赏任何其他将值设置为 n 维数组的想法,但指针方式似乎是最有效的,只是我无法弄清楚

提前致谢。

【问题讨论】:

  • 你想在这里存档什么?将一个普通的{ 1 2 3 4 5 6 } 数组复制到一个multidim { { 1 2 } { 3 4 } { 5 6 } } 数组中?
  • 将 {1,2,3,4,5} 复制到 sama 数据类型的多维数组中,这意味着 {1,2,3,4,5,6} -> {{1, 2,3}, {4,5,6}} 或 {1,2,3,4,5,6,7,8} -> {{{1,2},{3,4}},{{ 5,6},{7,8}}} 等等...一维数组到 ND 数组,其中 N 未知。
  • 这并没有真正回答我的问题...GetIndexes 到底在做什么?它看起来非常复杂,可能是了解您要在此处存档的内容的关键。
  • GetIndexes 返回 n 维数组的所有可能索引。例如:如果数组维度是 [2,4,5] 那么它将返回:{0,0,0} {0,0,1}{0,0,2}... {0,0,4} {0,1,0}, {0,1,1}.... 直到最后一个索引:{1,3,4} 它将按从小到大的顺序返回此 ND 数组的所有可能索引。跨度>
  • 提供一些例子

标签: c# arrays pointers multidimensional-array


【解决方案1】:

要复制内容,您可以使用:https://dotnetfiddle.net/vTzJv4

// 1D array
int[] values = new int[] {
    1, 2, 3,
    4, 5, 6
};
// 2D array
int[,] marr = new int[2,3];

// Copy here
System.Buffer.BlockCopy((Array)values, 0, (Array)marr, 0, (int)marr.LongLength * sizeof(int));

【讨论】:

  • 哇,我不认为缓冲区复制与不同维度的数组兼容。谢谢! :) 猜想我必须为每种元素类型做一个切换,因为它可能是一个字节数组以及浮点数/双精度数等等。 (所有原始类型)
猜你喜欢
  • 1970-01-01
  • 2015-07-06
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多