Find closest index by difference with BinarySearch

前端 未结 2 781
南笙
南笙 2021-02-20 18:14

I have a sorted array of about 500,000 ints. Currently I am selecting the correct index by taking the differences between my target int, and all of the elements, and then sortin

相关标签:
2条回答
  • 2021-02-20 18:47

    Just do the binary search, and if the result is negative you then find where it would be inserted and look at the next and previous entry - in other words, with your current code, check index and index - 1 (after checking that index isn't 0 :). Find out which is closer, and you're done.

    0 讨论(0)
  • 2021-02-20 18:51

    Here is a short demo , based on John Skeet's explantation. This method returns only dates that are between from Time and to Time. It assumes of course that the original array is sorted by time.

    private DateTime[] GetDataForEntityInInterval(DateTime fromTime, DateTime toTime)
            {
    
            DateTime[] allValues = GetAllValuesFromDB();
            int indexFrom = Array.BinarySearch(allValues, fromTime);
    
             if(indexFrom < 0)
             {
                 int indexOfNearest = ~indexFrom;
    
                 if (indexOfNearest == allValues.Length)
                 {
                     //from time is larger than all elements
                     return null;
                 }
                 else if (indexOfNearest == 0)
                 {
                     // from time is less than first item
                     indexFrom = 0;
                 }
                 else
                 {
                     // from time is between (indexOfNearest - 1) and indexOfNearest
                     indexFrom = indexOfNearest;
                 }
             }
    
             int indexTo = Array.BinarySearch(allValues, toTime);
             if (indexTo < 0)
             {
                 int indexOfNearest = ~indexTo;
    
                 if (indexOfNearest == allValues.Length)
                 {
                     //to time is larger than all elements
                     indexTo = allValues.Length - 1;
                 }
                 else if (indexOfNearest == 0)
                 {
                     // to time is less than first item
                     return null;
                 }
                 else
                 {
                     // to time is between (indexOfNearest - 1) and indexOfNearest
                     indexTo = Math.Max(0, indexOfNearest - 1);
                 }
             }
    
            int length = indexTo - indexFrom + 1;
            DateTime[] result = new DateTime[length];
            if (length > 0)
            {
                Array.Copy(allValues, indexFrom, result, 0, length);
            }
            return result;
    
        }
    
    0 讨论(0)
提交回复
热议问题