[英]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.