/// <summary> /// Finds the range of matches that are greater or equal than low value and lesser or equal to /// high value within the sorted sequence by means of a binary search. /// Example: /// <![CDATA[ /// int arr = { 1, 1, 2, 5, 5, 5, 8, 8, 10, 12, 12 }; /// IndexRangeWindow res = FindRange(3, 7); /// //res: [low:3 high:7 count:5] /// ]]> /// </summary> /// <param name="lowValue">The low value to search (the highest in the sequence, /// if sequence is reversed sort as set in constructor, this will be the higher value).</param> /// <param name="highValue">A value higher (further on) in the sequence.</param> /// <param name="index">The index at which to begin the search (0 by default).</param> /// <param name="length">The length of items to search after index (by default is set to the /// sequence length which was set in the Init or constructor).</param> public IndexRangeWindow FindRange(T lowValue, T highValue, int index = 0, int?length = null) { int low = index; int high = _GetHighFromInputLength(low, length); // --- both methods below do low,high bounds check so don't do here again --- // is low value already greater than high? if (compareTo(lowValue, highValue) > 0) { return(IndexRangeWindow.NoneFound); } // GET LOW int lowRangeIndex = FindLowRange(lowValue, low, high); if (lowRangeIndex > high || lowRangeIndex < 0) { return(IndexRangeWindow.NoneFound); } // GET HIGH int highRangeIndex = FindHighRange(highValue, lowRangeIndex, high); var range = new IndexRangeWindow(lowRangeIndex, highRangeIndex); return(range); }
/// <summary> /// Finds the range of matches of a single value within the sorted sequence /// by means of a binary search, see BinarySearch[T].FindSingleRange for further details. /// </summary> public static IndexRangeWindow BinarySearchFindRange <T>(IList <T> arr, T value, bool reverse = false, int index = 0, int?length = null, Func <T, T, int> comparer = null) { var bs = new BinarySearch <T>(arr, reverse, comparer); IndexRangeWindow result = bs.FindSingleRange(value, index, length); return(result); }
public IndexRangeWindow FindSingleRangeFromFoundLinear(T value, int foundIdx, int index = 0, int?count = null) { //FindSingleRangeFromFoundLinear if (foundIdx < 0) { return(IndexRangeWindow.NoneFound); } // BinaryRange r = new BinaryRange(foundIdx, foundIdx); // if(!r.Any) // return r; int low = foundIdx; int high = foundIdx; for (int i = foundIdx - 1; i >= index; i--) { T item = _getItemAt(i); if (compareTo(value, item) == 0) { --low; // --r.Low; } else { break; } } int sequenceLength = count ?? _collLength; for (int i = foundIdx + 1; i < sequenceLength; i++) { T item = _getItemAt(i); if (compareTo(value, item) == 0) { ++high; //++r.High; } else { break; } } var result = new IndexRangeWindow(low, high); return(result); }
/// <summary> /// Finds the range of matches of a single value within the sorted sequence /// by means of a binary search, see overload for further details. /// </summary> /// <param name="value">Value to search for. Both a FindLowRange and /// FindHighRange search will be performed on it.</param> /// <param name="index">Index</param> /// <param name="length">Count from Index to search on</param> public IndexRangeWindow FindSingleRange(T value, int index = 0, int?length = null) { int low = index; int high = length == null ? _collLength - index - 1 : (index + (int)length) - 1; // GET LOW int lowRangeIndex = FindLowRange(value, low, high); if (lowRangeIndex > high || lowRangeIndex < 0) { return(IndexRangeWindow.NoneFound); } // GET HIGH int highRangeIndex = FindHighRange(value, lowRangeIndex, high); var range = new IndexRangeWindow(lowRangeIndex, highRangeIndex); return(range); }