qse/samples/cmn/bh01.cpp

300 lines
5.6 KiB
C++
Raw Permalink Normal View History

2015-03-11 06:12:48 +00:00
#include <stdio.h>
#include <string>
#include <qse/cmn/BinaryHeap.hpp>
#include <qse/cmn/LinkedList.hpp>
#include <string.h>
class PosStr: public std::string
{
public:
PosStr (const char* str = ""): std::string(str), heap_pos((qse_size_t)-1) {};
PosStr (const PosStr& ps): std::string (ps), heap_pos(ps.heap_pos)
{
}
~PosStr()
{
}
qse_size_t heap_pos;
};
struct cstr_comparator
{
bool operator() (const char* v1, const PosStr& v2) const
{
//return strcmp (v1, v2.c_str()) > 0;
return strcmp (v1, v2.c_str()) < 0;
}
};
struct str_comparator
{
bool operator() (const PosStr& v1, const PosStr& v2) const
{
//return strcmp (v1.c_str(), v2.c_str()) > 0;
return strcmp (v1.c_str(), v2.c_str()) < 0;
}
};
typedef QSE::BinaryHeap<PosStr,str_comparator> StrHeap;
typedef QSE::LinkedList<PosStr> StrList;
class Container
{
public:
struct str_ptr_greater_than
{
bool operator() (const StrList::Node* v1, const StrList::Node* v2) const
{
//return strcmp (v1.c_str(), v2.c_str()) > 0;
return strcmp (v1->value.c_str(), v2->value.c_str()) > 0;
}
};
struct str_ptr_positioner
{
void operator() (StrList::Node* v, qse_size_t index) const
{
v->value.heap_pos = index;
}
};
typedef QSE::BinaryHeap<StrList::Node*,str_ptr_greater_than,str_ptr_positioner> StrPtrHeap;
StrList::Node* insert (const char* str)
{
StrList::Node* node = this->str_list.append (PosStr(str));
qse_size_t heap_pos = this->str_heap.insert (node);
return node;
}
bool isEmpty () const
{
QSE_ASSERT (this->str_list.isEmpty() == this->str_heap.isEmpty());
return this->str_list.isEmpty();
}
qse_size_t getSize() const
{
QSE_ASSERT (this->str_list.getSize() == this->str_heap.getSize());
return this->str_list.getSize();
}
const PosStr& getLargest () const
{
StrList::Node* node = this->str_heap.getValueAt(0);
return node->value;
}
void removeLargest ()
{
StrList::Node* node = this->str_heap.getValueAt(0);
this->str_heap.remove (0);
this->str_list.remove (node);
}
void remove (StrList::Node* node)
{
this->str_heap.remove (node->value.heap_pos);
this->str_list.remove (node);
}
StrList::Node* getHeapValueAt (qse_size_t index)
{
return this->str_heap.getValueAt(index);
}
StrList str_list;
StrPtrHeap str_heap;
};
struct IntComparator
{
bool operator() (int v1, int v2) const
{
//return !(v1 > v2);
//return v1 > v2;
return v1 < v2;
}
};
static StrHeap getStrHeap ()
{
char buf[100];
StrHeap h;
for (int i = 0; i < 25; i++)
{
sprintf (buf, "binary heap item %d", i);
h.insert (buf);
}
return h;
}
2015-03-11 06:12:48 +00:00
int main ()
{
char buf[20];
StrHeap h;
#define TOTAL 22
printf ("[TEST #1 - %d strings must be shown]\n", TOTAL * 2);
for (int i = 0; i < TOTAL; i++)
2015-03-11 06:12:48 +00:00
{
sprintf (buf, "hello %d", i);
h.insert (buf);
h.insert (buf);
}
if (h.getSize() != TOTAL * 2)
2015-03-11 06:12:48 +00:00
{
printf ("[FAILURE] ------------------------ \n");
2015-03-11 06:12:48 +00:00
}
else
{
for (qse_size_t i = 0; i < h.getSize(); i++)
{
printf ("%05d %s\n", (int)h.getIndex(h[i]), h[i].c_str());
}
}
printf ("\n");
2015-03-11 06:12:48 +00:00
//////////////////////////////////////////////////////////////////////////////
2015-03-11 06:12:48 +00:00
printf ("[TEST #2 - strings must be shown in ascending order]\n");
const char* x = h[0u].c_str();
std::string oldx;
while (true)
2015-03-11 06:12:48 +00:00
{
oldx = x;
printf ("%s\n", x);
2015-03-11 06:12:48 +00:00
h.remove (0);
if (h.isEmpty()) break;
x = h[0u].c_str();
if (strcmp (x, oldx.c_str()) < 0)
{
printf ("[FAILURE] ------------------------ \n");
break;
}
2015-03-11 06:12:48 +00:00
}
printf ("\n");
//////////////////////////////////////////////////////////////////////////////
2015-03-11 06:12:48 +00:00
printf ("[TEST #3 - integers must be shown in ascending order]\n");
{
QSE::BinaryHeap<int,IntComparator> h2;
h2.insert (70);
h2.insert (90);
h2.insert (10);
h2.insert (5);
h2.insert (88);
h2.insert (87);
h2.insert (300);
h2.insert (91);
h2.insert (100);
h2.insert (200);
int x = h2.getValueAt(0);
int oldx;
while (true)
{
oldx = x;
printf ("%d\n", x);
h2.remove (0);
if (h2.getSize() <= 0) break;
x = h2.getValueAt(0);
if (x < oldx)
{
printf ("[FAILURE] ------------------------ \n");
break;
}
}
2015-03-11 06:12:48 +00:00
}
printf ("\n");
//////////////////////////////////////////////////////////////////////////////
printf ("[TEST #4 - strings must be shown in the ascending order]\n");
{
StrHeap h (getStrHeap ());
2015-03-11 06:12:48 +00:00
const char* x = h.getValueAt(0).c_str();
std::string oldx;
while (true)
{
oldx = x;
printf ("%s\n", x);
h.remove (0);
if (h.isEmpty()) break;
x = h.getValueAt(0).c_str();
if (strcmp (x, oldx.c_str()) < 0)
{
printf ("[FAILURE] ------------------------ \n");
break;
}
}
}
printf ("\n");
//////////////////////////////////////////////////////////////////////////////
2015-03-11 06:12:48 +00:00
printf ("[TEST #5 - random test]\n");
2015-03-11 06:12:48 +00:00
{
Container c;
StrList::Node* node2, * node14;
for (qse_size_t i = 0; i < TOTAL; i++)
2015-03-11 06:12:48 +00:00
{
2015-03-17 16:06:07 +00:00
sprintf (buf, "hello %d", (int)i);
2015-03-11 06:12:48 +00:00
//c.insert (buf);
if (i == 2)
{
node2 = c.insert (buf);
printf ("2nd => %s\n", node2->value.c_str());
}
else if (i == 14)
{
node14 = c.insert (buf);
printf ("14th => %s\n", node14->value.c_str());
}
else c.insert (buf);
}
/*
for (int i = 0; i < c.getSize(); i++)
{
StrList::Node* node = c.getHeapValueAt(i);
printf ("%s %d\n", node->value.c_str(), (int)node->value.heap_pos);
}
*/
for (int i = 0; c.getSize() > 0; i++)
{
2015-03-11 06:12:48 +00:00
if (i == 3) c.remove (node2);
if (i == 5) c.remove (node14);
2015-03-11 06:12:48 +00:00
const char* largest = c.getLargest().c_str();
printf ("%s\n", largest);
2015-03-11 06:12:48 +00:00
c.removeLargest ();
}
}
return 0;
}