【问题标题】:Compare value with array and get closest value to it将值与数组进行比较并获得最接近的值
【发布时间】:2012-06-05 09:11:52
【问题描述】:

我是 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) 值是最接近我的“搜索值”的值?

【问题讨论】:

  • 选择最低的 -> 选择差异最小的值?
  • 澄清一下,您的 Searchvalue 是 p, which is 3001 in this case, and you want to compare it against your array w 并且您希望结果是 3000,这是数组中最接近 3001 的值。这是正确的吗?
  • @user982998 又添加了一个解决方案。

标签: c# arrays compare


【解决方案1】:

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

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 可能是,但实际上如果数字未排序,您的解决方案将不起作用。所以这是一个更普遍的解决方案。但是,如果您添加另一个 if(对于较低的最接近),它仍然可能会更快。
  • 你是对的,它仍然比你的解决方案快一点
  • @FelixK。感谢您的回答。
【解决方案2】:
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 仅用于调试/查看他是否正确选择了最低/最高
  • Dump 不是框架方法,OP 是 “C# 中的菜鸟”。所以我会解释它是一个 LinqPad 方法(或者干脆省略它)。 Enumerable.Min 的链接和 LINQ 的几句话也会有所帮助。
【解决方案3】:

根据您的代码,您可以通过非常简单的方式实现这一目标

    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)

【讨论】:

    【解决方案4】:
                    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;
                        }
                    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 2019-04-03
      • 2013-10-23
      相关资源
      最近更新 更多