public static int _binSearchEx(Obj[] objs, int first, int count, Obj obj) { int low = first; int high = first + count - 1; while (low <= high) { int mid = (int)(((long)low + (long)high) / 2); int res = obj.QuickOrder(objs[mid]); if (res == -1) { high = mid - 1; // objs[mid] > obj } else if (res == 1) { low = mid + 1; // objs[mid] < obj } else { return(mid); } } return(-low - 1); }
// If the element exists, return its index // Otherwise, return the -(I + 1) where I is the index of // the first element that is greater than the searched one public static int BinSearchEx(Obj[] objs, int first, int count, Obj obj) { int idx = _binSearchEx(objs, first, count, obj); if (idx >= 0) { Debug.Assert(objs[idx].IsEq(obj)); } else { int insIdx = -idx - 1; Debug.Assert(insIdx >= first & insIdx <= first + count); Debug.Assert(insIdx == first || objs[insIdx - 1].QuickOrder(obj) < 0); Debug.Assert(insIdx == first + count || obj.QuickOrder(objs[insIdx]) <= 0); } return(idx); }
public static int[] BinSearchRange(Obj[] objs, int offset, int length, Obj obj) { int first; int low = offset; int high = offset + length - 1; int lowerBound = low; int upperBound = high; while (low <= high) { int mid = (int)(((long)low + (long)high) / 2); int ord = obj.QuickOrder(objs[mid]); if (ord == -1) { upperBound = high = mid - 1; // objs[mid] > obj } else if (ord == 1) { lowerBound = low = mid + 1; // objs[mid] < obj } else { if (mid == offset || !objs[mid - 1].IsEq(obj)) { first = mid; low = lowerBound; high = upperBound; while (low <= high) { mid = (int)(((long)low + (long)high) / 2); ord = obj.QuickOrder(objs[mid]); if (ord == -1) { high = mid - 1; // objs[mid] > obj } else if (ord == 1) { low = mid + 1; // objs[mid] < obj } else { if (mid == upperBound || !objs[mid + 1].IsEq(obj)) { return new int[] { first, mid - first + 1 } } ; else { low = mid + 1; } } } // We're not supposed to ever get here. throw ErrorHandler.InternalFail(); } else { high = mid - 1; } } } return(new int[] { 0, 0 }); }
public static int[] BinSearchRange(int[] idxs, Obj[] major, Obj[] minor, Obj majorVal, Obj minorVal) { int offset = 0; int length = major.Length; int low = offset; int high = offset + length - 1; int lowerBound = low; int upperBound = high; while (low <= high) { int mid = (int)(((long)low + (long)high) / 2); int midIdx = idxs[mid]; int ord = majorVal.QuickOrder(major[midIdx]); if (ord == 0) { ord = minorVal.QuickOrder(minor[midIdx]); } if (ord == -1) { // major[mid] > majorVal | (major[mid] == majorVal & minor[mid] > minorVal) upperBound = high = mid - 1; } else if (ord == 1) { // major[mid] < majorVal | (major[mid] == majorVal) & minor[mid] < minorVal) lowerBound = low = mid + 1; } else { bool isFirst = mid == offset; if (!isFirst) { int prevIdx = idxs[mid - 1]; isFirst = !major[prevIdx].IsEq(majorVal) || !minor[prevIdx].IsEq(minorVal); } if (isFirst) { int first = mid; low = lowerBound; high = upperBound; while (low <= high) { mid = (int)(((long)low + (long)high) / 2); midIdx = idxs[mid]; ord = majorVal.QuickOrder(major[midIdx]); if (ord == 0) { ord = minorVal.QuickOrder(minor[midIdx]); } if (ord == -1) { // major[mid] > majorVal | (major[mid] == majorVal & minor[mid] > minorVal) high = mid - 1; } else if (ord == 1) { // major[mid] < majorVal | (major[mid] == majorVal) & minor[mid] < minorVal) low = mid + 1; } else { bool isLast = mid == upperBound; if (!isLast) { int nextIdx = idxs[mid + 1]; isLast = !major[nextIdx].IsEq(majorVal) || !minor[nextIdx].IsEq(minorVal); } if (isLast) { return(new int[] { first, mid - first + 1 }); } else { low = mid + 1; } } } // We're not supposed to ever get here. throw ErrorHandler.InternalFail(); } else { high = mid - 1; } } } return(new int[] { 0, 0 }); }