Reputation:
I want to make a function that gives an array returns the nearest element to a number.
here is some examples:
int[] arr = new int[] {12, 48, 50, 100};
my_function(1, arr); // returns 12.
my_function(40, arr); // returns 48.
my_function(49, arr); // returns 50; in two element with equal distance, returns greater number
my_function(70, arr); // returns 50.
my_function(10005, arr); // returns 100.
Sorry, I have no idea about how to write this function.
Upvotes: 3
Views: 387
Reputation: 5861
private int GetNearest(int[] array,int number)
{
return array.OrderBy(x => Math.Abs((long)x - number)).FirstOrDefault();
}
If you want to be sure that the larger number is before smaller number when the absolute difference is the same, add .ThenByDescending(a => a)
after OrderBy(x => Math.Abs((long)x - number))
private int GetNearest(int[] array,int number)
{
return array.OrderBy(x => Math.Abs((long)x - number)).ThenByDescending(a => a).FirstOrDefault();
}
Upvotes: 4
Reputation: 23238
This is a solution without using System.Linq
and with O(n)
complexity. You just go through array in loop and find a number with minimal difference, abs <= diff
condition allows you to return the latest number (50
for 49
instead of 48
) in sorted array. If difference equals 0
, it means that you find the exact number
var arr = new[] { 12, 48, 50, 100 };
int nearest = GetNearest(1, arr);
nearest = GetNearest(40, arr);
nearest = GetNearest(49, arr);
nearest = GetNearest(70, arr);
nearest = GetNearest(1005, arr);
int GetNearest(int number, int[] array)
{
int diff = int.MaxValue;
int result = 0;
foreach (var item in array)
{
var abs = Math.Abs(item - number);
if (abs == 0)
{
result = item;
break;
}
if (abs <= diff)
{
diff = abs;
result = item;
}
}
return result;
}
Upvotes: 1
Reputation: 684
I have approached it this way.
private static int nearest(int number, int[] numbers)
{
int min = numbers[0];
int max = numbers.OrderByDescending(a => a).FirstOrDefault();
if (number> max)
{
return max;
}
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i]<number && numbers[i+1]>number)
{
int lower = Math.Abs(numbers[i])-Math.Abs(number);
int upper = Math.Abs(numbers[i+1]) - Math.Abs(number);
if (Math.Abs(upper)>Math.Abs(lower))
{
return numbers[i];
}
else
{
return numbers[i+1];
}
}
}
return min;
}
Upvotes: 0
Reputation: 32286
If you know that the array is sorted then you can find the closest value like this in O(log n) time.
public int GetNearest(int value, int[] sortedArray)
{
var index = Array.BinarySearch(sortedArray, value);
// If we found a match then the closest is equal to the value.
if(index >= 0) return value;
// Otherwise it's the bitwise compliment to the index of the value just larger.
var largerIndex = ~index;
// If the index is the length of the array then all numbers are smaller,
//so take the last.
if(largerIndex == sortedArray.Length) return sortedArray[arr.Length - 1];
// If the index is 0 then all numbers are greater so take the first.
if(largerIndex == 0) return sortedArray[0];
// Now get the number that is just larger and just smaller and calculate the
// difference to each.
var larger = sortedArray[largerIndex];
var smaller = sortedArray[largerIndex - 1];
var largerDiff = larger - value;
var smallerDiff = value - smaller;
// If the diff to the smaller number is less then we take the smaller number
// otherwise the larger number is closer or the difference is the same in which
// case we take the larger number.
return smallerDiff < largerDiff ? smaller : larger;
}
Upvotes: 0
Reputation: 216303
A different way to get the result expected is to calculate the distance between the value passed and the array elements. Then get the element with the lowest 'distance' and find the matching index in the input array. You need Linq as well here.
int Nearest(int value, int[] arr)
{
var distances = arr.Select(x => Math.Abs(x - value)).ToList();
int min = distances.Min();
// Using LastIndexOf is important
// if you get two equal distances (I.E. 48/50 and passing 49)
return arr[distances.LastIndexOf(min)];
}
Upvotes: 1
Reputation: 1540
This works:
public static int my_function(int num, int[] arr)
{
var minDiff = Math.Abs(arr[0] - num);
var nearest = arr[0];
for (int i = 1; i < arr.Length; i++)
{
var diff = Math.Abs(arr[i] - num);
if (diff <= minDiff)
{
minDiff = diff;
nearest = arr[i];
}
}
return nearest;
}
Upvotes: 0