将值与数组进行比较并获取最接近它的值

3
我是一名C#的新手,正在努力学习这门语言。
请问您能否给我一个提示,如何比较数组和选取其中最小值?
例如:
Double[] w = { 1000, 2000, 3000, 4000, 5000 };

double min = double.MaxValue;
double max = double.MinValue;

foreach (double value in w)
{
    if (value < min)
        min = value;
    if (value > max)
        max = value;
}

Console.WriteLine(" min:", min); 

给我最小值w,现在该如何比较?

如果我有:

int p = 1001 + 2000;  // 3001

如何将现在的值与数组列表进行比较,并找出(3000)值是最接近我的“搜索值”的值?


2
选择最低的 -> 选择使差异最小的值? - Vlad
1
只是为了澄清,您的Searchvalue是p,这种情况下是3001,并且您想将其与数组w进行比较,并且希望结果为3000,这是最接近3001的数组中的值。这正确吗? - rikitikitik
@user982998 添加了另一种解决方案。 - Felix K.
4个回答

13

你可以通过一些简单的数学方法来做到这一点,同时有不同的方法。

LINQ

Double searchValue = ...;

Double nearest = w.Select(p => new { Value = p, Difference = Math.Abs(p - searchValue) })
                  .OrderBy(p => p.Difference)
                  .First().Value;

手动

Double[] w = { 1000, 2000, 3000, 4000, 5000 };

Double searchValue = 3001;
Double currentNearest = w[0];
Double currentDifference = Math.Abs(currentNearest - searchValue);

for (int i = 1; i < w.Length; i++)
{
    Double diff = Math.Abs(w[i] - searchValue);
    if (diff < currentDifference)
    {
        currentDifference = diff;
        currentNearest = w[i];
    }
}

经过测试100,000个元素后,我可以告诉你,你的LinQ比你的“手动”解决方案慢得多,但我想这并不新鲜,但我很惊讶我的解决方案比你的手动解决方案快2倍,我以为它们几乎是一样的,但也许Math.Abs()在你的解决方案中是导致缓慢的部分。 - WiiMaxx
@WiiMaxx 可能是这样,但实际上如果数字没有排序,你的解决方案是不起作用的。所以这是一个更普遍的解决方案。但是,如果你添加另一个 if(用于较低的最接近值),它可能会更快。 - Felix K.
你是对的,它仍然比你的解决方案快一点。 - WiiMaxx
@FelixK. 感谢您的回答。 - Siddharth

1
Double[] w = { 1000, 2000, 3000, 4000, 5000 };
var minimumValueFromArray = w.Min();

生成

1000,正如预期的那样,因为我们执行了Enumerable.Min

对于Enumerable.Max也是一样的,用于找出最大值:

Double[] w = { 1000, 2000, 3000, 4000, 5000 };
var maximumValueFromArray = w.Max();

考虑到您正在与double.MinValuedouble.MaxValue进行比较,我会假设您只想从数组中选择最小和最大的值。

如果这不是您要搜索的内容,请澄清。


double.MinValue 只是用于调试/查看是否正确选择了最低/最高值。 - user982998
1
“Dump” 不是一个框架方法,而且 OP 是一位“C# 新手”。所以我会解释它是 LinqPad 方法(或者干脆省略它)。提供 Enumerable.Min 的链接和几句话关于 LINQ 也会很有帮助。 - Tim Schmelter

0
基于你的代码,你可以以非常简单的方式实现这个。
    Double[] w = { 1000, 2000, 3000, 4000, 5000 }; // it has to be sorted

    double search = 3001;
    double lowerClosest = 0;
    double upperClosest = 0;


        for (int i = 1; i < w.Length; i++)
        {
            if (w[i] > search)
            {
                upperClosest = w[i];
                break; // interrupts your foreach
            }

        }
        for (int i = w.Length-1; i >=0; i--)
        {
            if (w[i] <= search)
            {
                lowerClosest = w[i];
                break; // interrupts your foreach
            }

        }

    Console.WriteLine(" lowerClosest:{0}", lowerClosest);
    Console.WriteLine(" upperClosest:{0}", upperClosest);
    if (upperClosest - search > search - lowerClosest)
        Console.WriteLine(" Closest:{0}", lowerClosest);
    else
        Console.WriteLine(" Closest:{0}", upperClosest);

    Console.ReadLine();

根据您搜索值的位置,这将是小于O(n)。

-2
                Performance wise custom code will be more use full. 

                List<int> results;
                int targetNumber = 0;
                int nearestValue=0;
                if (results.Any(ab => ab == targetNumber ))
                {
                    nearestValue= results.FirstOrDefault<int>(i => i == targetNumber );
                }
                else
                {
                    int greaterThanTarget = 0;
                    int lessThanTarget = 0;
                    if (results.Any(ab => ab > targetNumber ))
                    {
                        greaterThanTarget = results.Where<int>(i => i > targetNumber ).Min();
                    }
                    if (results.Any(ab => ab < targetNumber ))
                    {
                        lessThanTarget = results.Where<int>(i => i < targetNumber ).Max();
                    }

                    if (lessThanTarget == 0 )
                    {
                        nearestValue= greaterThanTarget;
                    }
                    else if (greaterThanTarget == 0)
                    {
                        nearestValue= lessThanTarget;
                    }
                    else if (targetNumber - lessThanTarget < greaterThanTarget - targetNumber )
                    {
                        nearestValue= lessThanTarget;
                    }
                    else
                    {
                            nearestValue= greaterThanTarget;
                    }
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接