Advertisement
Guest User

Untitled

a guest
May 18th, 2015
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.75 KB | None | 0 0
  1. // simpletest.C
  2. //
  3. // UE Algorithmen und Datenstrukturen - SS 2015 Universitaet Wien
  4. // Container - Projekt
  5. // https://cewebs.cs.univie.ac.at/ADS/ss15/
  6. //
  7. // Simples Testprogramm zur Ueberpruefung der Container-Funktionalitaet
  8. //
  9. // BEACHTEN:
  10. // (1) Die Zeichenfolge CONTAINERTYPE ist in der ganzen Datei durch den Klassennamen
  11. //     der Implementierung zu ersetzen (auch im #include).
  12. // (2) Der Elementdatentyp muss mit Compileroption -DETYPE=<typ> festgelegt werden,
  13. //     also zb -DETYPE=std::string
  14. // (3) Der zweite Templateparameter kann mit Compileroption -DSIZE=<n> festgelegt
  15. //     werden, also zb -DSIZE=13, andernfalls wird der Defaultwert verwendet.
  16. // (4) Das Testprogramm testet nicht alle Container-Methoden, es kann aber entsprechend
  17. //     erweitert werden.
  18. //
  19. // g++ -Wall -O3 --std=c++11 --pedantic-errors -DETYPE=std::string simpletest.C
  20. // g++ -Wall -O3 --std=c++11 --pedantic-errors -DETYPE=std::string -DSIZE=13 simpletest.C
  21.  
  22. #include <iostream>
  23. #include <sstream>
  24. #include <fstream>
  25. #include <string>
  26. #include <cstring>
  27. #include <cstdlib>
  28. #include <cctype>
  29. #include "LinearHashing.h"
  30.  
  31. #ifndef ETYPE
  32.  #error ETYPE not defined - compile with option -DETYPE=type
  33.  #endif
  34.  
  35. class Person;
  36. using ElementType = ETYPE;
  37.  
  38. const char helpstr[] =
  39.         "new ............................... create new Container\n"
  40.                 "delete ............................ delete Container\n"
  41.                 "add <key> [...] ................... add <key>(s) with Container::add(int)\n"
  42.                 "remove <key> [...] ................ remove <key>(s) with Container::remove(int)\n"
  43.                 "member <key> ...................... call Container::member(<key>)\n"
  44.                 "size .............................. call Container::size()\n"
  45.                 "empty ............................. call Container::empty()\n"
  46.                 "min ............................... call Container::min()\n"
  47.                 "max ............................... call Container::max()\n"
  48.                 "print ............................. print container with operator<<()\n"
  49.                 "apply [asc|desc|dontcare [<n>]] ... traverse container with apply (throw exception in nth call)\n"
  50.                 "trace ............................. toggle tracing on/off\n"
  51.                 "fadd <filename> ................... add values read from file <filename>\n"
  52.                 "fremove <filename> ................ remove values read from file <filename>\n"
  53.                 "radd [<n> [<seed>]] ............... add <n> random values, optionally reset generator to <seed>\n"
  54.                 "rremove [<n> [<seed>]] ............ remove <n> random values, optionally reset generator to <seed>\n"
  55.                 "quit .............................. quit program\n\n"
  56.                 "arguments surrounded by [] are optional\n";
  57.  
  58. void setrandom(int seed) { srand(seed); }
  59. template <typename E> E nextrandom() { return E(rand()); }
  60.  
  61. // Template-Spezialisierungen fuer Klasse std::string
  62.  
  63. template <> inline double doubleValue(const std::string& e) {
  64.     double rc = 0.; for (size_t i = e.length(); i--;) rc /= 256., rc += e[i]; return rc;
  65. }
  66. template <> inline size_t hashValue(const std::string& e) { return std::hash<std::string>()(e); }
  67. template <> std::string nextrandom() {
  68.     std::string rc;
  69.     for (int i = rand() / (RAND_MAX/4+1) + 4; i; --i) rc += char(rand() / (RAND_MAX/('z'-'a'+1) + 1) + 'a');
  70.     return rc;
  71. }
  72.  
  73. // Klasse Person mit allen für die Verwendung als Container-Elementdatentyp noetigen Methoden und Funktionen
  74.  
  75. class Person {
  76.     std::string vorname;
  77.     std::string nachname;
  78. public:
  79.     Person() { }
  80.     Person(std::string vorname, std::string nachname) : vorname(vorname), nachname(nachname) { }
  81.     bool operator==(const Person& p) const { return vorname == p.vorname && nachname == p.nachname; }
  82.     bool operator>(const Person& p) const { return nachname > p.nachname || (nachname == p.nachname && vorname > p.vorname); }
  83.  
  84.     std::ostream& print(std::ostream& o) const { return o << '[' << nachname << ", " << vorname << ']'; }
  85.     std::istream& read(std::istream& i) { return i >> vorname >> nachname; }
  86.     friend double doubleValue<Person>(const Person& e);
  87.     friend size_t hashValue<Person>(const Person& e);
  88.     friend size_t ordinalValue<Person>(const Person& e);
  89. };
  90.  
  91. inline std::ostream& operator<<(std::ostream& o, const Person& p) { return p.print(o); }
  92. inline std::istream& operator>>(std::istream& i, Person& p) { return p.read(i); }
  93.  
  94. // Template-Spezialisierungen fuer Klasse Person
  95.  
  96. template <> inline double doubleValue(const Person& e) { return doubleValue(e.nachname); }
  97. template <> inline size_t hashValue(const Person& e) { return hashValue(e.nachname) ^ hashValue(e.vorname); }
  98. template <> Person nextrandom() { return Person(nextrandom<std::string>(), nextrandom<std::string>()); }
  99.  
  100. bool match(const std::string& s, const char * c) {
  101.     return c && s.length() > 0 && s.length() <= std::strlen(c) && s.compare(0, s.length(), c, s.length()) == 0;
  102. }
  103.  
  104. std::istream& operator>>(std::istream& i, Order& o) {
  105.     std::string str;
  106.     i >> str;
  107.     o = match(str, "ascending") ? ascending : match(str, "descending") ? descending : dontcare;
  108.     return i;
  109. }
  110.  
  111. class ApplyTestException : public std::exception {
  112. public:
  113.     virtual const char * what() const noexcept override { return "exception not properly catched in apply()"; }
  114. };
  115.  
  116. int main() {
  117.  
  118.     LinearHashing<ElementType>* c = nullptr;
  119.     bool traceIt = false;
  120.     std::cout.setf(std::ios_base::boolalpha);
  121.  
  122.     while (true) {
  123.         if (traceIt) {
  124.             if (c) {
  125.                 std::cout << std::endl << "container:\n" << *c;
  126.             } else {
  127.                 std::cout << std::endl << "no container";
  128.             }
  129.         }
  130.         std::cout << std::endl << "> ";
  131.  
  132.         std::string cmdline;
  133.         if (!std::getline(std::cin, cmdline)) break;
  134.  
  135.         std::istringstream cmdstream(cmdline);
  136.         std::string cmd;
  137.  
  138.         cmdstream >> cmd;
  139.  
  140.         try {
  141.             if (cmd.length() == 0) {
  142.             } else if (match(cmd, "quit")) {
  143.                 break;
  144.             } else if (match(cmd, "new")) {
  145.                 if (c) {
  146.                     std::cerr << "container exists, 'delete' it first";
  147.                 } else {
  148. #ifdef SIZE
  149.            c = new LinearHashing<ElementType,SIZE>;
  150. #else
  151.            c = new LinearHashing<ElementType>;
  152. #endif
  153.                 }
  154.             } else if (match(cmd, "help") || cmd == "?") {
  155.                 std::cout << helpstr;
  156.             } else if (match(cmd, "trace")) {
  157.                 std::cout << "trace " << ((traceIt = !traceIt) ? "on" : "off");
  158.             } else if (!c) {
  159.                 std::cout << "no container (use 'new')";
  160.             } else {
  161.                 ElementType key;
  162.                 if (match(cmd, "delete")) {
  163.                     delete c;
  164.                     c = 0;
  165.                 } else if (match(cmd, "add")) {
  166.                     while (cmdstream >> key) { c->add(key); }
  167.                 } else if (match(cmd, "remove")) {
  168.                     while (cmdstream >> key) { c->remove(key); }
  169.                 } else if (match(cmd, "member")) {
  170.                     cmdstream >> key;
  171.                     std::cout << "returns " << c->member(key);
  172.                 } else if (match(cmd, "size")) {
  173.                     std::cout << "returns " << c->size();
  174.                 } else if (match(cmd, "empty")) {
  175.                     std::cout << "returns " << c->empty();
  176.                 } else if (match(cmd, "min")) {
  177.                     std::cout << "returns " << c->min();
  178.                 } else if (match(cmd, "max")) {
  179.                     std::cout << "returns " << c->max();
  180.                 } else if (match(cmd, "print")) {
  181.                     std::cout << *c;
  182.                 } else if (match(cmd, "apply")) {
  183.                     int n = 0;
  184.                     Order order;
  185.                     cmdstream >> order >> n;
  186.                     size_t rc1 = c->apply([&](const ElementType& e) {
  187.                         if (n>0 && !--n) throw ApplyTestException(); // test exception handling of apply()
  188.                         std::cout << e << ' ';
  189.                     }, order);
  190.                     std::cout << "\nreturns " << rc1;
  191.                 } else if (match(cmd, "fadd")) {
  192.                     std::string filename;
  193.                     cmdstream >> filename;
  194.                     std::ifstream keystream(filename.c_str());
  195.                     while (keystream >> key) { c->add(key); }
  196.                 } else if (match(cmd, "fremove")) {
  197.                     std::string filename;
  198.                     cmdstream >> filename;
  199.                     std::ifstream keystream(filename.c_str());
  200.                     while (keystream >> key) { c->remove(key); }
  201.                 } else if (match(cmd, "radd")) {
  202.                     int seed = -1, count = 1;
  203.                     cmdstream >> count >> seed;
  204.                     if (seed != -1) setrandom(seed);
  205.                     while (count-- > 0) c->add(nextrandom<ElementType>());
  206.                 } else if (match(cmd, "rremove")) {
  207.                     int seed = -1, count = 1;
  208.                     cmdstream >> count >> seed;
  209.                     if (seed != -1) setrandom(seed);
  210.                     while (count-- > 0) c->remove(nextrandom<ElementType>());
  211.                 } else {
  212.                     std::cout << cmd << "? try 'help'";
  213.                 }
  214.             }
  215.         } catch (ContainerException& e) {
  216.             std::cout << "catched ContainerException \"" << e.what() << "\"";
  217.         } catch (std::exception& e) {
  218.             std::cout << "catched std::exception \"" << e.what() << "\"";
  219.         } catch (...) {
  220.             std::cout << "OOPS! - catched something else";
  221.         }
  222.     }
  223.     return 0;
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement