mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
239 lines
5.8 KiB
C++
239 lines
5.8 KiB
C++
#include <Core/Core.h>
|
|
|
|
using namespace Upp;
|
|
|
|
template <class I, class Less>
|
|
void FwSort2(I begin, I end, const Less& less)
|
|
{
|
|
while(begin != end && begin + 1 != end) {
|
|
I min = begin;
|
|
I max = begin;
|
|
for(I i = begin + 1; i != end; i++) {
|
|
if(less(*i, *min))
|
|
min = i;
|
|
if(!less(*i, *max))
|
|
max = i;
|
|
}
|
|
IterSwap(begin, min);
|
|
IterSwap(--end, max == begin ? min : max);
|
|
begin++;
|
|
}
|
|
}
|
|
|
|
template <class I, class Less>
|
|
void FwSortSimple(I begin, I end, const Less& less)
|
|
{
|
|
while(begin != end) {
|
|
I min = begin;
|
|
for(I i = begin; ++i != end;)
|
|
if(less(*i, *min))
|
|
min = i;
|
|
IterSwap(begin++, min);
|
|
}
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline int SelectMin2(I ptr, int i, const Less& less)
|
|
{
|
|
return less(ptr[i + 1], ptr[i]);
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline int SelectMin3(I ptr, int i, const Less& less)
|
|
{
|
|
int l = SelectMin2(ptr, less);
|
|
I h = ptr + 2;
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin4(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin2(ptr, less);
|
|
I h = SelectMin2(ptr + 2, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin5(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin4(ptr, less);
|
|
I h = ptr + 4;
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin6(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin4(ptr, less);
|
|
I h = SelectMin2(ptr + 4, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin7(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin4(ptr, less);
|
|
I h = SelectMin3(ptr + 4, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin8(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin4(ptr, less);
|
|
I h = SelectMin4(ptr + 4, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin9(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = ptr + 8;
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin10(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin2(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin11(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin3(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin12(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin4(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin13(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin5(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin14(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin6(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin15(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin7(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
inline I SelectMin16(I ptr, const Less& less)
|
|
{
|
|
I l = SelectMin8(ptr, less);
|
|
I h = SelectMin8(ptr + 8, less);
|
|
return less(*l, *h) ? l : h;
|
|
}
|
|
|
|
template <class I, class Less>
|
|
void FwSort(I begin, int len, const Less& less)
|
|
{
|
|
switch(len) {
|
|
case 16: IterSwap(begin, SelectMin16(begin, less)); begin++;
|
|
case 15: IterSwap(begin, SelectMin15(begin, less)); begin++;
|
|
case 14: IterSwap(begin, SelectMin14(begin, less)); begin++;
|
|
case 13: IterSwap(begin, SelectMin13(begin, less)); begin++;
|
|
case 12: IterSwap(begin, SelectMin12(begin, less)); begin++;
|
|
case 11: IterSwap(begin, SelectMin11(begin, less)); begin++;
|
|
case 10: IterSwap(begin, SelectMin10(begin, less)); begin++;
|
|
case 9: IterSwap(begin, SelectMin9(begin, less)); begin++;
|
|
case 8: IterSwap(begin, SelectMin8(begin, less)); begin++;
|
|
case 7: IterSwap(begin, SelectMin7(begin, less)); begin++;
|
|
case 6: IterSwap(begin, SelectMin6(begin, less)); begin++;
|
|
case 5: IterSwap(begin, SelectMin5(begin, less)); begin++;
|
|
case 4: IterSwap(begin, SelectMin4(begin, less)); begin++;
|
|
case 3: IterSwap(begin, SelectMin3(begin, less)); begin++;
|
|
case 2: IterSwap(begin, SelectMin2(begin, less));
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
void Dump(const Vector<T>& data)
|
|
{
|
|
String s;
|
|
for(int q = 0; q < data.GetCount(); q++)
|
|
s << data[q] << ' ';
|
|
LOG(s);
|
|
}
|
|
|
|
CONSOLE_APP_MAIN
|
|
{
|
|
#ifdef _DEBUG
|
|
Vector<int> x;
|
|
x << 40 << 20 << 4 << 10 << 11 << 17 << 2 << 12;
|
|
FwSort(x.Begin(), x.GetCount(), StdLess<int>());
|
|
Dump(x);
|
|
Vector<String> y;
|
|
y << "40" << "20" << "4" << "10" << "11" << "17" << "2" << "12";
|
|
FwSort(y.Begin(), y.GetCount(), StdLess<String>());
|
|
Dump(y);
|
|
for(int i = 0; i < 10; i++) {
|
|
Vector<int> data;
|
|
int n = rand() % 16;
|
|
for(int q = 0; q < n; q++)
|
|
data.Add(rand() % 100);
|
|
Dump(data);
|
|
FwSort(data.Begin(), data.GetCount(), StdLess<int>());
|
|
Dump(data);
|
|
LOG("----");
|
|
}
|
|
#else
|
|
Vector< Vector<int> > set;
|
|
for(int i = 0; i < 1000; i++) {
|
|
Vector<int>& data = set.Add();
|
|
int n = rand() % 15;
|
|
n = 8;
|
|
for(int q = 0; q < n; q++)
|
|
data.Add(rand() % 100);
|
|
}
|
|
double x = 100.0 * set.GetCount();
|
|
RDUMP(x);
|
|
dword time = GetTickCount();
|
|
while(time + 3000 > GetTickCount()) {
|
|
Vector< Vector<int> > s;
|
|
s <<= set;
|
|
{
|
|
RTIMING("Simple FW sort");
|
|
for(int i = 0; i < s.GetCount(); i++)
|
|
ForwardSort(s[i].Begin(), s[i].End(), StdLess<int>());
|
|
}
|
|
s <<= set;
|
|
{
|
|
RTIMING("Normal FW sort");
|
|
for(int i = 0; i < s.GetCount(); i++)
|
|
ForwardSort(s[i].Begin(), s[i].End(), StdLess<int>());
|
|
}
|
|
s <<= set;
|
|
{
|
|
RTIMING("New FW sort");
|
|
for(int i = 0; i < s.GetCount(); i++)
|
|
FwSort(s[i].Begin(), s[i].GetCount(), StdLess<int>());
|
|
}
|
|
}
|
|
#endif
|
|
}
|