Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// <summary>
- /// Binary search algorithms require sorted collection.
- /// Searches a collection for a <paramref name="target"/> element and returns the index of the element,
- /// or the index of the next closest larger value available.
- /// If repeating values exist the value of <paramref name="operation"/> is used to return the
- /// first or last index of the target element.
- /// </summary>
- /// <typeparam name="T">A type implementing the IComparable interface</typeparam>
- /// <param name="target">The searched element</param>
- /// <param name="source">The source collection - should be sorted</param>
- /// <param name="left">left boundry -> the bottom of the range</param>
- /// <param name="right">right boundry -> the top of the range</param>
- /// <param name="operation">
- /// An integer with value +1 or -1 that will be used to either decrease or increase the index of an exact match
- /// so its first or last index can be detected.
- /// </param>
- /// <returns>Always returns and index -> of the exact match if exists or the next larger value</returns>
- public static int BinarySearchForValueClosestToTarget<T>(
- T target, IList<T> source, int left, int right, int operation) where T : IComparable<T>
- {
- int pick = left;
- while (left < right)
- {
- pick = (left + right) / 2;
- // If exact match is found continue lineary because there may be equal values
- // the direction to continue is dictated by the operation variable (-1 or +1)
- if (source[pick].CompareTo(target) == 0)
- {
- while (source[pick].CompareTo(target) == 0)
- {
- pick += operation;
- if (pick < 0 || source.Count <= pick)
- {
- break;
- }
- }
- // Undoes the last operation
- pick -= operation;
- return pick;
- }
- if (source[pick].CompareTo(target) > 0)
- {
- right = pick;
- }
- else
- {
- left = pick + 1;
- }
- }
- // Continue lineary from the last tested position to find the exact index at which
- // neighbours of the first side are smaller and on the other side - larger
- if (source[pick].CompareTo(target) > 0)
- {
- while (source[pick].CompareTo(target) > 0)
- {
- pick--;
- if (pick < 0)
- {
- break;
- }
- }
- pick += 1;
- }
- else
- {
- while (source[pick].CompareTo(target) < 0)
- {
- pick++;
- if (pick >= source.Count)
- {
- pick--;
- break;
- }
- }
- }
- return pick;
- }
Advertisement
Add Comment
Please, Sign In to add comment