如何在c#中获得每十年最接近的值?

时间:2017-07-30 11:52:19

标签: c# algorithm math listbox

我通过使用计时器并将它们添加到列表框或datagridview中来获取数据。我需要获得每几十年的价值,例如:10,20,30,40,50..

但并不总是数据和我想要的一样多。有一个示例数据; 10.15 14.45 19.65 22.18 27.89 30.15 31.15 37.46 42.01 ...

根据上面的数据,我想在我的代码中列出这些数据;

10.15 as 10 19.65 as 20 30.15 as 30 42.01 as 40 ...

如你所见,我不想错过任何十年。 在我的代码label1.text represents velocitylabel2.Text represents timewatch is a stopwatch首先,我将数据收集到lisboxes,然后将它们带到datagirview.Here是我的代码;

private void timer2_Tick(object sender, EventArgs e)
{
    watch.Start();
    var time = watch.Elapsed.TotalSeconds;
    if (Math.Round(Convert.ToDouble(label1.Text)) % 10 == 0)
    {
        listBoxTime.Items.Add(label2.Text);
        listBoxVelocity.Items.Add(label1.Text);
        p = dataGridView1.Rows.Add();
        for (int i = 1; i < listBoxTime.Items.Count; i++)
        {
            dataGridView1.Rows[p].Cells[0].Value = listBoxVelocity.Items[i].ToString();
            dataGridView1.Rows[p].Cells[1].Value = listBoxTime.Items[i].ToString();

        }
    }
}

正如我之前所说,我应该做些什么来获得每十年最接近的数据,而不会遗漏任何十年。

2 个答案:

答案 0 :(得分:0)

你可以将数字除以10,然后将它们四舍五入,然后乘以10。检查两者之间的差异,并将其与之前的差异进行比较。

更新(删除了上一个答案) 现在刚刚降到最低点。可能不是最优雅/通用的方式,但它应该工作。 的 UPDATE2 : 替换了C#6代码

class Numbers {
    public int Rounded { get; set; }
    public double Number { get; set; }
    public double Difference
    {
        get { return Math.Abs(Rounded - Number); }
    }
}
class Program
{
    static void Main(string[] args)
    {
        var numbers = new [] {10.15, 14.45, 19.65, 22.18, 27.89, 30.15, 31.15, 37.46, 42.01};
        var decades = new List<Numbers>();

        foreach (var number in numbers)
        {
            var rounded = (int)Math.Round(number / 10, MidpointRounding.AwayFromZero) * 10;
            var found = decades.FirstOrDefault(x => x.Rounded == rounded);

            if (found == null)
                decades.Add(new Numbers { Rounded = rounded, Number = number });
            else if (found.Difference > Math.Abs(rounded - number))
                found.Number = number;
        }

        foreach (var number in decades)
            Console.WriteLine($"{number.Number} as {number.Rounded}");

        Console.ReadKey();
    }
}

<强>结果:

10.15 as 10
19.65 as 20
30.15 as 30
42.01 as 40

我不确定你是否想要保留那些没有削减的数字,但这不应该太难添加。

更改

public double Difference => MathAbs(Rounded - Number);

C#6 Alternative-1

public double Difference() {
    return Math.Abs(Rounded - Number);
}

C#6 Alternative-2

public double Difference { 
    {
        get { return Math.Abs(Rounded - Number); }
    }
}

答案 1 :(得分:0)

以下解决方案显示了一种可能的方法。要使用此功能,请务必将this Nuget package添加到项目中。

代码基本上舍入到最近的十年,然后选择最接近(即最小差异)的条目作为示例。

using System;
using System.Collections.Generic;
using System.Linq;
using MoreLinq;

class Program
{
    private static IEnumerable<DecadeAndClosest> GroupByDecade(double[] input)
    {
        var rounded = input.Select(z => new
        {
            original = z,
            rounded = Math.Round(z / 10, MidpointRounding.AwayFromZero) * 10
        });
        var roundedWithDifference =
            rounded.Select(z => new { z.original, z.rounded, difference = Math.Abs(z.original - z.rounded) });
        var finalResults = roundedWithDifference.GroupBy(z => z.rounded)
            .Select(z => new DecadeAndClosest() { Decade = z.Key, Example = z.MinBy(Y => Y.difference).original });
        return finalResults;
    }

    public class DecadeAndClosest
    {
        public double Decade { get; set; }
        public double Example { get; set; }
    }

    static void Main(string[] args)
    {
        var input = new[]
        {
            10.15,
            14.45,
            19.65,
            22.18,
            27.89,
            30.15,
            31.15,
            37.46,
            42.01
        };

        var finalResults = GroupByDecade(input);

        foreach (var indiv in finalResults)
        {
            Console.WriteLine(string.Format("{0} - {1}", indiv.Decade, indiv.Example));
        }

        Console.ReadLine();
    }
}