user11955706
user11955706

Reputation:

function to returns the nearest element of array to an integer

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

Answers (6)

Farhad Zamani
Farhad Zamani

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

Pavel Anikhouski
Pavel Anikhouski

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

Gnyasha
Gnyasha

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

juharr
juharr

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

Steve
Steve

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

Hadi Samadzad
Hadi Samadzad

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

Related Questions