2012-12-24 62 views
-3

我有一個float數組元素,我試圖刪除彼此接近的元素。 也就是說如果有兩個元素相隔小於0.4(例如15.1和15.3),我想刪除第二個元素。 0.4應該是該算法的輸入參數。刪除太靠近彼此的數組元素

該數組已經按特定順序(而不是升序/降序)排序,我需要保留該順序。

+1

我的建議是:請出示你已經嘗試了什麼... –

+1

應該在接近對第二個元素被刪除,即使如果第一個元素也是刪除的候選人? –

+0

http://www.whathaveyoutried.com? – MadSkunk

回答

2

我已經創建了一個ApproximateFloatComparer類,如下所示:

public class ApproximateFloatComparer : IComparer<float> 
{ 
    public float Range { get; set; } 

    public ApproximateFloatComparer(float range) 
    { 
     this.Range = range; 
    } 

    public int Compare(float x, float y) 
    { 
     if (x - this.Range < y && x + this.Range > y) 
      return 0; 
     else return x.CompareTo(y); 
    } 
} 

然後創建一個方法進行重複數據刪除:

public static List<float> Deduplicate(List<float> floats, float range) 
{ 
    var dedup = new List<float>(); 
    var comparer = new ApproximateFloatComparer(range); 
    foreach (var @float in floats) 
     if (!dedup.Any(f => comparer.Compare(f, @float) == 0)) 
      dedup.Add(@float); 
    return dedup; 
} 

然後結合這一切:

var floats = new List<float>() { 5, 8, 2, 13, 6, 9, 4, 3, 2.1f, 8.6f, 2.2f }; 
floats = Deduplicate(floats, 0.4f); 
+0

太好了。爲我工作。非常感謝,傑森。 –

2

通過簡單的while ,使用List<float>而不是array,有一個擴展方法:

public static void Deduplicate(this List<float> values, float delta, int decimals) 
{ 
    int index = 0; 
    while (index < values.Count) 
    { 
     float value = values[index]; 

     int i = index + 1; 
     while (i < values.Count) 
     { 
      if (Math.Round(Math.Abs(value - values[i]), decimals) < delta) 
       values.RemoveAt(i); 
      else 
       ++i; 
     } 
     ++index; 
    } 
} 

,並使用它:

List<float> values = new List<float> { 3.4f, 1, 2, 3, 4, 1.2f, 2.5f, 3.6f, 1 }; 
values.Deduplicate(0.4f, 5);//  { 3.4f, 1, 2, 4,  2.5f   } 
values.Deduplicate(0.4f, 10);//  { 3.4f, 1, 2, 3, 4,  2.5f   } 
+0

謝謝康斯坦丁。這是就地過濾的一個很好的解決方案。 –