2012-05-30 25 views
2

我想檢查列表值是否具有某種「親密度」級別。有沒有一個好的算法來做到這一點?獎金積分爲最pythonic的方式。給定一個整數列表,確定70%的值是否在其中一個值的20%以內

有效

[1,7,8,9] 
[3,4,100,101,102,103,104,105] 

無效

[1,8,9] 
[1,10] 
[100,200,300,400,500] 
+3

有一個很好的算法。這就是所謂的方差 – ControlAltDel

+0

@aix問題中沒有提到方法的有效性。我很確定這裏有足夠的信息來提供有效的實施。標題給出了什麼是有效的,什麼不是有效的定義。 – Zach

+0

實施這種親密度檢查幾乎是微不足道的。問題是這是否是一個很好的接近觀念。 –

回答

1

對於小列出了此爲O(n^2)算法就足夠了:

def is_close(l): 
    for n in l: 
     c = sum([1 for x in l if x >= 0.8 *n and x <= 1.2 * n]) 
     if c >= 0.7 * len(l): 
      return True 
    return False 

print is_close([1,7,8,9]) 
print is_close([3,4,100,101,102,103,104,105]) 
print is_close([1,8,9]) 
print is_close([1,10]) 
print is_close([100,200,300,400,500]) 

輸出是:

True 
True 
False 
False 
False 
+1

你的測試可能太嚴格了。應該是'> =','<=' –

+0

好點:)謝謝 - 現在已經修好了。 :) –

+1

'c> 0.7'太;) –

7
+1

如果使用numpy,則可以使用內置函數numpy.var(array)計算方差。 – abought

+0

我看不出如何工作。考慮'[1 999997,999998,999999,1000000,1000001,1000002,1000003,100000000000000000,100000000000000000000000000000]'。我們有70%的值在某個值的20%以內,但差異非常大。 –

0

這是一個算法,需要n logn時間。

sort the array 
for i in range(len(array)) 
    begin = binary search an index such that array[begin] >= array[i]*0.2 
    end = binary search an index such that array[end]*0.2 <= array[i] 
    if (end - begin) <= len(array) * 0.7 
     70% of the values are within %20 of array[i] 
     i.e all elements between begin and end are within 20% of array[i] 

幾種優化,包括改變迭代順序都是可能的。

1

下面是一個已經排序的陣列a一個簡單的線性時間算法(如實施例中,否則它需要在O(n log n)時間預先排序)。這個想法是構建和測試在給定位置low開始的每個最大子序列。

low = middle = high = 1 
while (low <= length (a)) 
    advance middle to the largest i such that a[i]*0.8<=a[low] 
    advance high to the largest i such that a[i]<=a[middle]*1.2 
    if ((high-low+1)/length(a)>=0.7) output(true) 
    low = low + 1 
return (false); 

由於lowmiddlehigh1通過length(a)總是增加,運行時間總是length(a)線性的。

如果需要a的匹配子序列,則可以輸出a[low]...a[high]而不是true

+0

基本上是一個很好的解決方案,只是幾點:你不需要全部直到下端達到數組末端,「高」達到「長度(a)」或「低」達到'0.3 *長度(a)'就足夠了。另外,我不會僅僅將'low'加1,我會將'middle'增加1,然後'low',直到a [low]> = 0.8 * a [middle],然後再將'middle'增加到最大的'我'與'a [i] * 0.8 <= a [低]',然後'高'。沒有太大的區別,但是如果數組中間有大的步驟,它會減少工作量。無論如何,這裏最好的解決方案是+1。 –

相關問題