我有一个常数的列表。我需要在数字列表中找到最接近x的数字。关于如何实现这个算法的任何想法?查找数字列表中最接近的数字
回答
那么,你不能这样做比O(N)
快,因为你必须检查所有的数字,以确保你有最接近的。这就是说,为什么不使用简单的变化来找到最小值,寻找一个与最小绝对差值的变量,它与x?
如果你可以说列表是从头开始排序的(它允许随机访问,就像数组一样),那么更好的方法是使用二分搜索。当您在索引i(没有找到x)时结束搜索时,只需从该元素及其邻居中选择最佳元素即可。
它可以通过SortedList做到:
Blog post on finding closest number
如果你正在寻找数只有搜索的复杂性是O(日志(n))的复杂性。列表建设将花费O(n * log(n))
如果您要将项目插入列表的次数比您要查询最接近的数字多得多,那么最佳选择是使用List并使用朴素算法来查询最近的数字。每个搜索将花费O(n),但插入的时间将减少到O(n)。
一般的复杂性:如果集合有ñ号和搜索q倍 -
列表:O(n+q*n)
排序清单:O(n*log(n)+q*log(n))
意义,从一些q排序列表将提供更好的复杂性。
private int? FindClosest(IEnumerable<int> numbers, int x)
{
return
(from number in numbers
let difference = Math.Abs(number - x)
orderby difference, Math.Abs(number), number descending
select (int?) number)
.FirstOrDefault();
}
Null表示没有最接近的数字。如果有两个具有相同差异的数字,它将选择最接近于零的数字。如果两个数字的距离为零,则选择正数。
编辑回应埃里克的评论:
这里是一个具有相同的语义版本,但使用Min
操作。它需要实施IComparable<>
,所以我们可以使用Min
,同时保留每个距离随附的数字。我也使它成为易用性的扩展方法:
public static int? FindClosestTo(this IEnumerable<int> numbers, int targetNumber)
{
var minimumDistance = numbers
.Select(number => new NumberDistance(targetNumber, number))
.Min();
return minimumDistance == null ? (int?) null : minimumDistance.Number;
}
private class NumberDistance : IComparable<NumberDistance>
{
internal NumberDistance(int targetNumber, int number)
{
this.Number = number;
this.Distance = Math.Abs(targetNumber - number);
}
internal int Number { get; private set; }
internal int Distance { get; private set; }
public int CompareTo(NumberDistance other)
{
var comparison = this.Distance.CompareTo(other.Distance);
if(comparison == 0)
{
// When they have the same distance, pick the number closest to zero
comparison = Math.Abs(this.Number).CompareTo(Math.Abs(other.Number));
if(comparison == 0)
{
// When they are the same distance from zero, pick the positive number
comparison = this.Number.CompareTo(other.Number);
}
}
return comparison;
}
}
LINQ的迷人用途。但是,我注意到这是O(n lg n)和O(n)的多余空间。如果使用Min序列运算符而不是排序,则可以在O(n)时间和O(1)空间中执行此操作。 – 2010-01-01 16:26:36
此外,你还没有完全消除这个问题的陈述。如果有两个具有相同差异的数字,并且两个数字都接近于零,会怎么样? – 2010-01-01 16:30:47
好点。我通过'数字降序'命令来确保选择正数(在没有行为要求的情况下,这是最合理的决定)。我将研究'Min'解决方案。感谢您的反馈Eric! – 2010-01-01 16:36:32
我想这个数组是无序的。在订购它可以更快
我认为最简单和最快的方法是使用线性算法寻找最小值或最大值,而不是比较值,你会比较这个和针之间的差异的绝对值。
在C++(我不能C#,但是这将是相似的)可以代码如下所示:
// array of numbers is haystack
// length is length of array
// needle is number which you are looking for (or compare with)
int closest = haystack[0];
for (int i = 0; i < length; ++i) {
if (abs(haystack[ i ] - needle) < abs(closest - needle)) closest = haystack[i];
}
return closest;
是“针”一些特殊的术语,我不知道的 – 2010-01-01 16:10:58
“大海捞针”:?d – 2010-01-01 16:13:34
“针”和“干草堆”是其常与搜索算法中使用的表达式 – Gaim 2010-01-01 16:14:14
一般人在这个网站你会不会做你的功课。既然你没有发布代码,我也不会发布代码。但是,这是一种可能的方法。
遍历列表中,减去从x中的列表中的号码。取这个差值的绝对值,并将它与先前得到的最好结果进行比较,如果当前差值小于以前的最佳结果,则从列表中保存当前值。在循环结束时,你会得到你的答案。
OP确实使用了“作业”标签。他不会试图在你身上拉一个快速的。 – 2010-01-01 16:23:33
懒惰我没有检查这一点,但不应该在该工作
private int FindClosest(IEnumerable<int> numbers, int x)
{
return
numbers.Aggregate((r,n) => Math.Abs(r-x) > Math.Abs(n-x) ? n
: Math.Abs(r-x) < Math.Abs(n-x) ? r
: r < x ? n : r);
}
哈斯克尔:
import Data.List (minimumBy)
import Data.Ord (comparing)
findClosest :: (Num a, Ord a) => a -> [a] -> Maybe a
findClosest _ [] = Nothing
findClosest n xs = Just $ minimumBy (comparing $ abs . (+ n)) xs
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;
}
}
- 1. 查找最接近给定数字的数组中的数字
- 2. 查找离阵列中所有数字最近的数字
- 3. 查找字典中与给定数字最接近的值
- 4. 用于查找数组中数字列表的最近元素的SQL查询
- 5. SQL找到最接近的数字
- 6. 查找数组中最接近的值与linq列表?
- 7. Python - 查找数字列表中的最大数字
- 8. 在Python列表中查找“最接近”的字符串(按字母顺序)
- 9. 查找最接近我的参数的数据表中的行
- 10. Java - 如何从最接近特定数字的散列图中查找值?
- 11. 阵列中最接近的数字,但在垄断表
- 12. 试图在数组中找到最接近的数字-Infinity JavaScript
- 13. 从列中查找最接近的值并从列中返回数字(在列表中)
- 14. 使用排序在列表中找出两个最接近的数字
- 15. 查找VBA中列数据中最接近的值
- 16. 浮点数 - 最接近1.7的数字
- 17. 多列查找并返回下一列(最接近的数值)
- 18. 相对于列表中最接近的数字对列表进行排序python
- 19. 查找数字列表中的“空白”
- 20. Ocaml - 查找列表中的字数
- 21. 如何找到哪个值最接近C中的数字?
- 22. 列表中的最大查找字段
- 23. 查找列表中的最近点数n
- 24. 寻找高效算法在整数列表中寻找最接近的整数
- 25. 如何设计算法来查找数字列表中最大的数字?
- 26. 查找数组最大最接近给定数数
- 27. 搜索最接近的较低数字
- 28. 在数据库中查找最接近的数值
- 29. 查找数字的近似平方根
- 30. 在txt文件中查找字符串并显示最接近的整数
你能使用排序列表? – 2010-01-01 16:06:36
不要忘记考虑不寻常的情况。 (1)如果没有最接近的数字?和(2)如果有两个不同的最接近的数字? – 2010-01-01 16:09:02