繁体   English   中英

C#数组问题(拆分)

[英]C# array question (split)

问题很简单 - 比方说,我得到了函数,它接收数组作为参数

void calc(double[] data)

如何在两个子阵列中“分割”这些数据并传递给这样的子函数

calc_sub(data(0, length/2));
cals_sub(data(length /2, length /2));

我希望,你有了这个想法 - 在c ++中我会写这个

void calc(double * data, int len)
{
   calc_sub(data, len / 2); //this one modifies data!!
   calc_sub(data + len / 2, len / 2); //this one modifies data too!!
}

如何在没有无意的内存复制的情况下在C#中做同样的事情? 我需要2个内存副本。 1)从数据到分割数据2)calc_sub 3)从分割数据回到数据! 这是浪费时间和记忆的巨大浪费!

最简单的可能是使用LINQs TakeSkip扩展方法:

int half = data.Length / 2;
double[] sub1 = data.Take(half).ToArray();
double[] sub2 = data.Skip(half).ToArray();

简短的回答是,要获得一个子阵列,你必须创建一个新的数组并复制元素......或者如果你使用的是c ++,那你就是memcpying。

现在,为什么不采取偏移/计数方法? 当调用calc_sub(blargh[] array) ,改为使用calc_sub(blargh[] array, int offset, int count)

这基本上是将指针传递给start / half-pos元素并告诉函数只能处理数组元素的一半的c#方式。


我应该注意,除非你正在使用巨大的双阵列,否则你真的不应该担心这一点。 64位= 8个字节。 即使你有1000个元素的数组,那是8000字节,~8 kB的内存,你可以在不到一秒的时间内免费获得...

现在,在可能的情况下保存内存总是一个好主意,但我认为这是不成熟的优化。

我还应该注意,数组是通过引用传递的,因为它们实际上是对象,而不是整数或字符串,所以这种方法是最好的内存方式[它不会复制数组; 它提供了类似于指向数组对象的指针,但它的局限性在于修改函数中的数组将修改在函数调用之外传递的数组。

根据calc_sub的作用,您可以创建一个IEnumerable类,它接受数组并迭代数组的某些部分。 ArraySegment这样的东西,但更好

继续编写自己的子阵列函数,如下所示:

public static class ArrayExtensions
{
  T[] SubArray<T>(this T[] arr, int startIndex,int count)
  {
    var sub = new T[count];
    Array.Copy(arr,startIndex,sub,o,count);
    return sub;
  }
}

然后你可以使用它像:

void calc(double[] data)
{
  var half = data.Length /2;
  data.SubArray(0, half ));
  data.SubArray(half , half ));
}

如果可以使calc_sub方法采用IEnumerable<double>而不是double[] ,则可以使用扩展方法创建返回数组部分的表达式:

void calc(double[] data) {
  int half = data.Length / 2;
  calc_sub(data.Take((half));
  calc_sub(data.Skip(half));
}

这样您就不必将数据复制到新数组,表达式将返回原始数组中的项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM