0

我有一个像这样的十进制数字列表:

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

我想这样分组这些数字:如果第一个和第二个数字之间的差是 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

你的问题在于:

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

它应该是:

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

顺便说一句,我不知道你在做什么......当你生成这样的 voodoocode 时,你真的需要学会逐步使用调试器。

于 2013-11-12T11:02:44.473 回答
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 回答