Beispiel #1
0
        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);
        }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
        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 });
        }
Beispiel #4
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 });
        }