kidroca

BinarySearchForValueClosestToTarget

Nov 9th, 2015
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.71 KB | None | 0 0
  1. /// <summary>
  2. /// Binary search algorithms require sorted collection.
  3. /// Searches a collection for a <paramref name="target"/> element and returns the index of the element,
  4. /// or the index of the next closest larger value available.
  5. /// If repeating values exist the value of <paramref name="operation"/> is used to return the
  6. /// first or last index of the target element.
  7. /// </summary>
  8. /// <typeparam name="T">A type implementing the IComparable interface</typeparam>
  9. /// <param name="target">The searched element</param>
  10. /// <param name="source">The source collection - should be sorted</param>
  11. /// <param name="left">left boundry -> the bottom of the range</param>
  12. /// <param name="right">right boundry -> the top of the range</param>
  13. /// <param name="operation">
  14. /// An integer with value +1 or -1 that will be used to either decrease or increase the index of an exact match
  15. /// so its first or last index can be detected.
  16. /// </param>
  17. /// <returns>Always returns and index -> of the exact match if exists or the next larger value</returns>
  18. public static int BinarySearchForValueClosestToTarget<T>(
  19.     T target, IList<T> source, int left, int right, int operation) where T : IComparable<T>
  20. {
  21.     int pick = left;
  22.     while (left < right)
  23.     {
  24.         pick = (left + right) / 2;
  25.  
  26.         // If exact match is found continue lineary because there may be equal values
  27.         // the direction to continue is dictated by the operation variable (-1 or +1)
  28.         if (source[pick].CompareTo(target) == 0)
  29.         {
  30.             while (source[pick].CompareTo(target) == 0)
  31.             {
  32.                 pick += operation;
  33.                 if (pick < 0 || source.Count <= pick)
  34.                 {
  35.                     break;
  36.                 }
  37.             }
  38.  
  39.             // Undoes the last operation
  40.             pick -= operation;
  41.  
  42.             return pick;
  43.         }
  44.  
  45.         if (source[pick].CompareTo(target) > 0)
  46.         {
  47.             right = pick;
  48.         }
  49.         else
  50.         {
  51.             left = pick + 1;
  52.         }
  53.     }
  54.  
  55.     // Continue lineary from the last tested position to find the exact index at which
  56.     // neighbours of the first side are smaller and on the other side - larger
  57.     if (source[pick].CompareTo(target) > 0)
  58.     {
  59.         while (source[pick].CompareTo(target) > 0)
  60.         {
  61.             pick--;
  62.             if (pick < 0)
  63.             {
  64.                 break;
  65.             }
  66.         }
  67.  
  68.         pick += 1;
  69.     }
  70.     else
  71.     {
  72.         while (source[pick].CompareTo(target) < 0)
  73.         {
  74.             pick++;
  75.             if (pick >= source.Count)
  76.             {
  77.                 pick--;
  78.                 break;
  79.             }
  80.         }
  81.     }
  82.  
  83.     return pick;
  84. }
Advertisement
Add Comment
Please, Sign In to add comment