0

私はそのような10進数のリストを持っています:

0.01
0.03
0.10
0.18
0.24
0.28
0.30
0.31
0.33
0.55
2.34
3.37
9.19
9.22
10.28

この数値を次のようにグループ化したいと思います。最初の数値と 2 番目の数値の差が 0.02 の場合。これは KeyValuePair リストの同じキーにある必要があります..

私は以下のような方法を持っています:

private List<KeyValuePair<int, float>> NumberingAngles(List<float> angleList)
{
    List<KeyValuePair<int, float>> numberedList = new List<KeyValuePair<int, float>>();
    numberedList.Clear();
#region BETA ACILARI TIPLENDIR
    float sonDeger = 0f;
    int z = 0;
    float ilkDeger = 0f;
    int mB = 2;
    float difference = 0f;
    float tipFarki = 0f;
    foreach (float item in angleList)
    {

        difference = Convert.ToSingle((item - sonDeger).ToString("0.00"));

        if (difference > 0.02f)
        {
            numberedList.Add(new KeyValuePair<int, float>(mB, item));
            sonDeger = item;
            mB++;
        }
        else
        {
            if (z == 0)
            {
                ilkDeger = item;
                z++;
            }
            tipFarki = item - ilkDeger;
            if (tipFarki > 0.02f)
            {
                numberedList.Add(new KeyValuePair<int, float>((mB - 1), item));
                sonDeger = item;
                mB++;
                ilkDeger = 0f;
                z = 0;
            }
            else
            {
                numberedList.Add(new KeyValuePair<int, float>((mB - 1), item));
                sonDeger = item;
            }
        }             
    }
#endregion
    return numberedList;
}

問題は次のとおりです。KeyValuePair リストで結果を取得すると、7 番のように一部のキーが欠落しています。以下に示すように、6 から 8 にジャンプします。どうすればこの問題を解決できますか..多分これは誰かにとって非常に簡単に解決できる..

結果は以下のようなものです..

1 0.01
1 0.03
2 0.10
3 0.18
4 0.24
5 0.28
5 0.30
6 0.31
6 0.33
8 0.55
9 2.34
10 3.37
11 9.19
12 9.22
13 10.28
4

3 に答える 3

1

私は単にこれを書き直し、少しリファクタリングを行いました。出てくるものは次のとおりです。

特定の範囲の値に属するすべての要素を保持するスロット クラス:

public class Slot
{
    private double _LowerBound;
    private double _UpperBound;
    private List<double> _Values;

    public Slot(double lowerBound, double upperBound)
    {
        if (upperBound < lowerBound)
            throw new ArgumentOutOfRangeException("The upper bound must be greater or equal the lower bound.");

        _LowerBound = lowerBound;
        _UpperBound = upperBound;

        _Values = new List<double>();
        _Values.Add(lowerBound);
        Values = _Values.AsReadOnly();
    }

    public ReadOnlyCollection<double> Values { get; private set; }

    public void Add(double value)
    {
        if (!IsResponsible(value))
        {
            var message = String.Format("The value {0} is not greater or equal {1} or less or equal {2}.", value, _LowerBound, _UpperBound);
            throw new ArgumentOutOfRangeException(message);
        }

        _Values.Add(value);
    }

    public bool IsResponsible(double value)
    {
        return value >= _LowerBound
               && value <= _UpperBound;
    }

    public override string ToString()
    {
        return String.Format("Range: {0} - {1}, Elements: {2}", _LowerBound, _UpperBound, _Values.Count);
    }
}

定義されたすべての範囲を保持する責任がある SlotCollection クラス:

public class SlotCollection : IEnumerable<KeyValuePair<int, double>>
{
    private List<Slot> _Slots;
    private double _TolerancePerSlot;

    public SlotCollection(double tolerancePerSlot)
    {
        if(tolerancePerSlot < 0)
            throw new ArgumentException("tolerancePerSlot must be greater or equal zero.", "tolerancePerSlot");

        _TolerancePerSlot = tolerancePerSlot;
        _Slots = new List<Slot>();
        Slots = new ReadOnlyCollection<Slot>(_Slots);
    }

    public ReadOnlyCollection<Slot> Slots { get; private set; }

    public void Add(IEnumerable<double> values)
    {
        foreach (var value in values)
        {
            Add(value);
        }
    }

    public IEnumerator<KeyValuePair<int, double>> GetEnumerator()
    {
        for (int i = 0; i < _Slots.Count; i++)
        {
            yield return new KeyValuePair<int, double>(i, _Slots[i].Values.First());
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    private void Add(double value)
    {
        var matchingSlot = _Slots.FirstOrDefault(slot => slot.IsResponsible(value));

        if (matchingSlot == null)
        {
            matchingSlot = new Slot(value, value + _TolerancePerSlot);
            _Slots.Add(matchingSlot);
        }
        else
        {
            matchingSlot.Add(value);
        }
    }
}

ある種の入力例:

var inputs = new List<double>()
{
    0.01, 0.03, 0.10, 0.18,
    0.24, 0.28, 0.30, 0.31,
    0.33, 0.55, 2.34, 3.37,
    9.19, 9.22, 10.28
};

上記のコードの使用例:

var slots = new SlotCollection(0.02);
slots.Add(inputs);

// Spit out the desired user output.
foreach (var kvp in slots)
{
    Console.WriteLine(kvp.Key + " " + kvp.Value);
}

Console.WriteLine();

// Output a more in depth view of the data distribution.
foreach (var slot in slots.Slots)
{
    Console.WriteLine(slot);

    foreach (var value in slot.Values)
    {
        Console.WriteLine("\t" + value);
    }

    Console.WriteLine();
}

このクラスの設計はまだ完璧にはほど遠いことは承知していますが、この問題をもう少しうまく解決するための良い出発点になるはずです。

于 2013-11-12T12:22:23.520 に答える
0

これを行う別の方法:

float[] values = 
        {
            0.01f,
            0.03f,
            0.10f,
            0.18f,
            0.24f,
            0.28f,
            0.30f,
            0.31f,
            0.33f,
            0.55f,
            2.34f,
            3.37f,
            9.19f,
            9.22f,
            10.28f
        };


        Dictionary<int, float[]> kvp = new Dictionary<int, float[]>();
        int j = 1;
        for (int i = 0; i < values.Length; i++)
        {
            if (i + 1 <= values.Length - 1)
            {
                if (Math.Round(values[i + 1] - values[i], 2) == .02d)
                {
                    kvp.Add(j, new float[] { values[i], values[i + 1] });
                    i++;                       
                }
                else
                    kvp.Add(j, new float[] { values[i] });
            }
            else               
                kvp.Add(j, new float[] { values[i] });

                j++;
        }

        foreach (var item in kvp)
        {             
            foreach (var i in item.Value)
            {
                Console.WriteLine(item.Key + " " + i);
            }             
        }

出力:

1 0.01
1 0.03
2 0.1
3 0.18
4 0.24
5 0.28
5 0.3
6 0.31
6 0.33
7 0.55
8 2.34
9 3.37
10 9.19
11 9.22
12 10.28
于 2013-11-12T12:01:36.933 に答える
0

あなたの問題は次のとおりです。

numberedList.Add(new KeyValuePair<int, float>(mB, item));

そのはず:

numberedList.Add(new KeyValuePair<int, float>(mB - 1, item));

ところで、私はあなたが何をしているのか見当がつきません... そのようなブードゥーコードを生成するときは、デバッガーを使ってステップスルーすることを本当に学ぶ必要があります.

于 2013-11-12T11:02:44.473 に答える