Пример #1
0
        public static ArrayIterator <T> LowerBound <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            T val,
            Func <T, T, bool> comp
            )
        {
            var count = first.Distance(last);

            while (count > 0)
            {
                var it   = first;
                var step = count / 2;
                it = it.GetAdvanced(step);
                if (comp(it.GetCurrent(), val))
                {
                    it     = it.GetNext();
                    first  = it;
                    count -= step + 1;
                }
                else
                {
                    count = step;
                }
            }
            return(first);
        }
Пример #2
0
        public static ArrayIterator <T> SearchN <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            int count,
            T val,
            Func <T, T, bool> pred
            )
        {
            var limit = first.GetAdvanced(first.Distance(last) - count);

            while (first.NotEqual(limit))
            {
                var it = first;
                var i  = 0;
                while (pred(val, it.GetCurrent()))
                {
                    it = it.GetNext();
                    if (++i == count)
                    {
                        return(first);
                    }
                }
                first = first.GetNext();
            }
            return(last);
        }
Пример #3
0
        public static ArrayIterator <T> PartitionPoint <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, bool> pred
            )
        {
            var n = first.Distance(last);

            while (n > 0)
            {
                var it   = first;
                var step = n / 2;
                it.GetAdvanced(step);
                if (pred(it.GetCurrent()))
                {
                    first = it.GetNext();
                    n    -= step + 1;
                }
                else
                {
                    n = step;
                }
            }
            return(first);
        }
Пример #4
0
        public static ArrayIterator <T> IsHeapUntil <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            var len = first.Distance(last);
            var p   = 0;
            var c   = 1;
            var pp  = first;

            while (c < len)
            {
                var cp = first.GetAdvanced(c);
                if (comp(pp.GetCurrent(), cp.GetCurrent()))
                {
                    return(cp);
                }
                c++;
                cp = cp.GetNext();
                if (c == len)
                {
                    return(last);
                }
                if (comp(pp.GetCurrent(), cp.GetCurrent()))
                {
                    return(cp);
                }
                p++;
                pp = pp.GetNext();
                c  = 2 * p + 1;
            }
            return(last);
        }
Пример #5
0
        public static bool IsPermutation <T>(
            this ArrayIterator <T> first1,
            ArrayIterator <T> last1,
            ArrayIterator <T> first2,
            Func <T, T, bool> pred
            )
        {
            first1.Mismatch(last1, first2, pred, out first1, out first2);
            if (first1.IsEqual(last1))
            {
                return(true);
            }
            var last2 = first2;

            last2 = last2.GetAdvanced(first1.Distance(last1));
            for (var it1 = first1; it1.NotEqual(last1); it1 = it1.GetNext())
            {
                if (first1.Find(it1, it1.GetCurrent(), pred).IsEqual(it1))
                {
                    var n = first2.Count(last2, it1.GetCurrent(), pred);
                    if (n == 0 || it1.Count(last1, it1.GetCurrent(), pred) != n)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #6
0
 public static void SortHeap <T>(
     this ArrayIterator <T> first,
     ArrayIterator <T> last,
     Func <T, T, bool> comp
     )
 {
     while (first.Distance(last) > 1)
     {
         last = last.GetPrev();
         Swap(first, last);
         AdjustHeap(first.Array, first.Index, first.Index, last.Index, comp);
     }
 }
Пример #7
0
        public static void PushHeap <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            if (first.Distance(last) < 2)
            {
                return;
            }
            last = last.GetPrev();
            var temp   = last.GetCurrent();
            var parent = first.GetAdvanced((first.Distance(last) - 1) / 2);

            while (first.Distance(last) > 0 && comp(parent.GetCurrent(), temp))
            {
                last.SetCurrent(parent.GetCurrent());
                last   = parent;
                parent = first.GetAdvanced((first.Distance(last) - 1) / 2);
            }
            last.SetCurrent(temp);
        }
Пример #8
0
 public static void PopHeap <T>(
     this ArrayIterator <T> first,
     ArrayIterator <T> last,
     Func <T, T, bool> comp
     )
 {
     if (first.Distance(last) < 2)
     {
         return;
     }
     last = last.GetPrev();
     Swap(first, last);
     AdjustHeap(first.Array, first.Index, first.Index, last.Index, comp);
 }
Пример #9
0
        public static void InplaceMerge <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> middle,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            if (first.Index >= middle.Index || middle.Index >= last.Index)
            {
                return;
            }
            if (last.Index - first.Index == 2)
            {
                if (comp(middle.GetCurrent(), first.GetCurrent()))
                {
                    Swap(first, middle);
                }
                return;
            }
            ArrayIterator <T> firstCut;
            ArrayIterator <T> secondCut;

            if (middle.Index - first.Index > last.Index - middle.Index)
            {
                firstCut  = first.GetAdvanced(first.Distance(middle) / 2);
                secondCut = middle.LowerBound(last, firstCut.GetCurrent(), comp);
            }
            else
            {
                secondCut = middle.GetAdvanced(middle.Distance(last) / 2);
                firstCut  = first.UpperBound(middle, secondCut.GetCurrent(), comp);
            }
            Rotate(firstCut, middle, secondCut);
            middle = firstCut.GetAdvanced(middle.Distance(secondCut));
            InplaceMerge(first, firstCut, middle, comp);
            InplaceMerge(middle, secondCut, last, comp);
        }
Пример #10
0
        public static void MakeHeap <T>(
            this ArrayIterator <T> first,
            ArrayIterator <T> last,
            Func <T, T, bool> comp
            )
        {
            var dist = first.Distance(last);

            if (dist < 2)
            {
                return;
            }
            var parent = (dist - 2) / 2;

            do
            {
                AdjustHeap(first.Array, first.Index, first.Index + parent, last.Index, comp);
            }while (parent-- != 0);
        }