簡體   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