-2

float要素の配列があり、互いに近い要素を削除しようとしています。つまり、間隔が0.4未満の2つの要素(15.1と15.3など)がある場合は、2番目の要素を削除します。0.4はアルゴリズムの入力パラメータである必要があります。

配列はすでに特定の順序(昇順/降順ではない)で並べ替えられており、その順序を保持する必要があります。

4

2 に答える 2

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);
于 2012-12-24T04:13:47.463 に答える
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          }
于 2012-12-24T04:28:56.913 に答える