Jeff Johnson
Jeff Johnson

Reputation: 1097

Finding the closest integer value, rounded down, from a given array of integers

I am trying to figure out the best way to find the closest value, ROUNDED DOWN, in a List of integers using any n that is between two other numbers that are stored in a List. The all integers in this situation will ALWAYS be unsigned, in case that helps.

The assumptions are as follows:

For example:

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 };
int myNumber = 9000;
int theAnswer; // should be 8500

for (int i = 0; i < numbers.Count; i++) {
    if (i == numbers.Count - 1) {
      theAnswer = numbers[i];
      break;
    } else if (myNumber < numbers[i + 1]) {
      theAnswer = numbers[i];
      break;
    }
}

The previous code example works without any flaws.

Is there a better more succint way to do it?

Upvotes: 1

Views: 1197

Answers (4)

user4003407
user4003407

Reputation: 22122

You can use List<T>.BinarySearch instead of enumerating elements of list in sequence.

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 };
int myNumber = 9000;

int r=numbers.BinarySearch(myNumber);
int theAnswer=numbers[r>=0?r:~r-1];

Upvotes: 5

Roman Bezrabotny
Roman Bezrabotny

Reputation: 186

Please try this code:

List<int> numbers = new List<int>() { 0, 2000, 4000, 8000, 8500, 9101, 10010 };
int myNumber = 9000;

int theAnswer = numbers[numbers.Count - 1];

if (theAnswer > myNumber)
{
    int l = 0, h = numbers.Count - 1, m;
    do
    {
        m = (int)((double)(myNumber - numbers[l]) / (double)(numbers[h] - numbers[l]) * (h - l) + l);
        if (numbers[m] > myNumber) h = m; else l = m;
    }   
    while ((h - l) != 1);
    theAnswer = numbers[l];
}

Upvotes: 0

Giorgos Betsos
Giorgos Betsos

Reputation: 72175

Filter list obtaining all values less than the myNumber and return last one:

theAnswer = numbers.Where(x => x <= myNumber ).Last();

Upvotes: 5

Eric J.
Eric J.

Reputation: 150118

A list can be indexed.

Start at the index in the middle of the list. If you found the exact number, you are good. If the number is less than the target number, search in the middle of the range from the start of the list to one less than the middle of the list. If the number is greater than the target number, work with the opposite half of the list. Continue this binary search until you find either an exact match, or the adjacent numbers that are smaller and larger than the target number.

Select the smaller of the two.

Upvotes: 0

Related Questions