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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }