簡體   English   中英

在C#中計算數組頻率分布的最快方法是什么?

[英]What is the fastest way to calculate frequency distribution for array in C#?

我只是想知道這個計算的最佳方法是什么。 假設我有一個值的輸入數組和邊界數組 - 我想計算/ bucketize邊界數組中每個段的頻率分布。

使用桶搜索是不是一個好主意?

實際上我發現這個問題用.Net / C#計算集合的頻率分布

但是我不明白如何使用桶來達到這個目的,因為每個桶的大小在我的情況下可能會有所不同。

編輯:在所有的討論之后我有內部/外部循環解決方案,但是我仍然希望在這種情況下消除帶有字典的內部循環以獲得O(n)性能,如果我理解正確的話我需要將輸入值散列到存儲桶索引中。 所以我們需要某種具有O(1)復雜度的哈希函數? 有什么想法怎么做?

Bucket Sort已經是O(n ^ 2)最壞的情況,所以我在這里只做一個簡單的內/外循環。 由於您的存儲桶數組必須比輸入數組短,因此請將其保留在內部循環中。 由於您使用的是自定義存儲桶大小,因此實際上沒有可以消除內部循環的數學技巧。

int[] freq = new int[buckets.length - 1];
foreach(int d in input)
{
    for(int i = 0; i < buckets.length - 1; i++)
    {
         if(d >= buckets[i] && d < buckets[i+1])
         {
             freq[i]++;
             break;
         }
    }
}

它也是O(n ^ 2)最壞的情況,但你無法擊敗代碼簡單性。 我不擔心優化,直到它成為一個真正的問題。 如果你有一個更大的桶陣列,你可以使用某種二進制搜索。 但是,由於頻率分布通常<100個元素,我懷疑你會看到很多真實的性能優勢。

如果您的輸入數組表示真實世界數據(帶有模式),並且邊界數組很大,可以在內部循環中反復迭代它,您可以考慮以下方法:

  • 首先對輸入數組進行排序。 如果您使用真實數據,我建議您考慮Timsort - Wiki 它為可在實際數據中看到的模式提供了非常好的性能保證。

  • 遍歷排序數組並將其與邊界數組中的第一個值進行比較:

    • 如果輸入數組中的值小於邊界 - 則增加此邊界的頻率計數器
    • 如果輸入數組中的值大於邊界 - 轉到邊界數組中的下一個值並增加新邊界的計數器。

在代碼中它看起來像這樣:

Timsort(myArray);
int boundPos; 
boundaries = GetBoundaries(); //assume the boundaries is a Dictionary<int,int>()

for (int i = 0; i<myArray.Lenght; i++) {
  if (myArray[i]<boundaries[boundPos]) { 
     boundaries[boubdPos]++;
  }
  else {
    boundPos++;
    boundaries[boubdPos]++;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM