mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +00:00
TArray Binary Search
This commit is contained in:
parent
b2cb4b0a6d
commit
cc51b486e0
1 changed files with 125 additions and 0 deletions
|
@ -355,6 +355,105 @@ public:
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!! THIS REQUIRES AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
|
||||||
|
bool IsSorted()
|
||||||
|
{
|
||||||
|
for(unsigned i = 1; i < Count; i++)
|
||||||
|
{
|
||||||
|
if(Array[i] < Array[i-1]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Func>
|
||||||
|
bool IsSorted(Func lt)
|
||||||
|
{
|
||||||
|
for(unsigned i = 1; i < Count; i++)
|
||||||
|
{
|
||||||
|
if(lt(Array[i], Array[i-1])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
|
||||||
|
// !!! AND AN ELEMENT TYPE THAT'S COMPARABLE WITH THE LT OPERATOR !!!
|
||||||
|
//
|
||||||
|
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||||
|
unsigned int SortedFind(const T& item, bool exact = true) const
|
||||||
|
{
|
||||||
|
if(Count == 0) return 0;
|
||||||
|
if(Count == 1) return (item < Array[0]) ? 0 : 1;
|
||||||
|
|
||||||
|
unsigned int lo = 0;
|
||||||
|
unsigned int hi = Count - 1;
|
||||||
|
|
||||||
|
while(lo <= hi)
|
||||||
|
{
|
||||||
|
int mid = lo + ((hi - lo) / 2);
|
||||||
|
|
||||||
|
if(Array[mid] < item)
|
||||||
|
{
|
||||||
|
lo = mid + 1;
|
||||||
|
}
|
||||||
|
else if(item < Array[mid])
|
||||||
|
{
|
||||||
|
hi = mid - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(exact)
|
||||||
|
{
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (lo == Count || (item < Array[lo])) ? lo : lo + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// !!! THIS REQUIRES A SORTED OR EMPTY ARRAY !!!
|
||||||
|
//
|
||||||
|
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||||
|
template<typename Func>
|
||||||
|
unsigned int SortedFind(const T& item, Func lt, bool exact = true) const
|
||||||
|
{
|
||||||
|
if(Count == 0) return 0;
|
||||||
|
if(Count == 1) return lt(item, Array[0]) ? 0 : 1;
|
||||||
|
|
||||||
|
unsigned int lo = 0;
|
||||||
|
unsigned int hi = Count - 1;
|
||||||
|
|
||||||
|
while(lo <= hi)
|
||||||
|
{
|
||||||
|
int mid = lo + ((hi - lo) / 2);
|
||||||
|
|
||||||
|
if(lt(Array[mid], item))
|
||||||
|
{
|
||||||
|
lo = mid + 1;
|
||||||
|
}
|
||||||
|
else if(lt(item, Array[mid]))
|
||||||
|
{
|
||||||
|
if(mid == 0) break; // prevent negative overflow due to unsigned numbers
|
||||||
|
hi = mid - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(exact)
|
||||||
|
{
|
||||||
|
return Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (lo == Count || lt(item, Array[lo])) ? lo : lo + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Contains(const T& item) const
|
bool Contains(const T& item) const
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -462,6 +561,21 @@ public:
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned SortedAddUnique(const T& obj)
|
||||||
|
{
|
||||||
|
auto f = SortedFind(obj, true);
|
||||||
|
if (f == Size()) Push(obj);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Func>
|
||||||
|
unsigned SortedAddUnique(const T& obj, Func lt)
|
||||||
|
{
|
||||||
|
auto f = SortedFind(obj, lt, true);
|
||||||
|
if (f == Size()) Push(obj);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
bool Pop ()
|
bool Pop ()
|
||||||
{
|
{
|
||||||
if (Count > 0)
|
if (Count > 0)
|
||||||
|
@ -542,6 +656,17 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SortedInsert (const T &item)
|
||||||
|
{
|
||||||
|
Insert (SortedFind (item, false), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Func>
|
||||||
|
void SortedInsert (const T &item, Func lt)
|
||||||
|
{
|
||||||
|
Insert (SortedFind (item, lt, false), item);
|
||||||
|
}
|
||||||
|
|
||||||
void ShrinkToFit ()
|
void ShrinkToFit ()
|
||||||
{
|
{
|
||||||
if (Most > Count)
|
if (Most > Count)
|
||||||
|
|
Loading…
Reference in a new issue