home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 November / Chip_2000-11_cd2.bin / chplus / Itercpp / ITERATOR.CPP
C/C++ Source or Header  |  2000-10-02  |  5KB  |  204 lines

  1. ////////////////////////////////////
  2. // Soubor Iterator.cpp
  3. // Ukazuje mozny zpusob deklarace iteratoru a jejich vyuziti
  4. // pro deklaraci sablony funkce pro trideni kontejneru
  5. //
  6. // Odladeno v C++Builderu 5, lze ale snadno upravit i 
  7. // pro starsi prekladace C++
  8. ///////////////////////////////////
  9.  
  10.  
  11. #include <iostream.h>
  12. #include <stdlib.h>
  13. #include <conio.h>
  14. #include <exception.h>
  15.  
  16.  
  17. const N = 10; // Pocet prvku seznamu
  18. typedef int T;
  19.  
  20. // Nejake pole, aby bylo co tridit
  21. int A[ N ] = {2,4,6,8,1,3,5,7,9,0};
  22.  
  23. // Pokud Vas prekladac nepodporuje vykjimky, nahradte
  24. // prikaz throw exception() volanim tetop funkce
  25. // a odstrante hlavickovy soubor <exception.h>
  26. void Chyba(){cout << "prusvih" << endl; exit(1);}
  27.  
  28. struct prvek {// prvek seznamu
  29.   T data;
  30.   prvek* dalsi;
  31. };
  32.  
  33. class seznam // Jednosmerny seznam se zarazkou
  34. {
  35.   prvek *prvni, *zarazka;
  36. public:
  37.   class Iterator; /* //ve starsich prekladacich musi byt tato deklarace zapsana zde jako vnorena
  38.   {
  39.     prvek* p;
  40.   public:
  41.     Iterator(prvek* _p=0): p(_p){}; 
  42.     T& operator*();// Operatory prom iterator
  43.     Iterator& operator++();
  44.     int operator ==(Iterator j) {return p == j.p;}
  45.     int operator !=(Iterator j) {return !(*this == j);}
  46.   };                */
  47.   friend class seznam::Iterator;
  48.  
  49.   seznam(); // Konstruktor a destruktor
  50.   ~seznam();
  51.   void VlozNaKonec(T co);// Vloz danou hodnotu do noveho prvku na konci seznamu
  52.   T VyjmiPrvni();// Odstran prvni prvek seznamu
  53.   Iterator begin();// Vraci iterator ukazujici na pocatek seznamu
  54.   Iterator end();// Vraci iterator ukazujici za posledni prvek seznamu
  55.   Iterator Najdi(T co);// Najdi prvek obsahujici danou hodnotu
  56. };
  57.  
  58. class seznam::Iterator // Iterator na seznamu
  59. {
  60.   prvek* p;// Ukazatel na aktualni prvek
  61. public:
  62.   Iterator(prvek* _p=0): p(_p){}; // Konstruktor
  63.   T& operator*();// "Dereferencovani" iteratoru (pristup k hodnote ulozene v prvku)
  64.   Iterator& operator++();// Prejdi na dalsi prvek
  65.   int operator ==(Iterator j) {return p == j.p;}// Porovnani iteratoru
  66.   int operator !=(Iterator j) {return !(*this == j);}
  67. };
  68.  
  69. seznam::Iterator seznam::begin() {return Iterator(prvni);}
  70. seznam::Iterator seznam::end() {return Iterator(zarazka);}
  71.  
  72. seznam::seznam()// Konstruktor
  73. {
  74.  zarazka = prvni = new prvek;
  75.  prvni -> dalsi = 0;
  76. }
  77.  
  78. void seznam::VlozNaKonec(T co)
  79. {
  80.  zarazka -> dalsi = new prvek;
  81.  zarazka -> data = co;
  82.  zarazka = zarazka -> dalsi;
  83.  zarazka -> dalsi = 0;
  84. }
  85.  
  86. T seznam::VyjmiPrvni()
  87. {
  88.  T a = prvni->data;
  89.  prvek* pom = prvni;
  90.  prvni = prvni->dalsi;
  91.  delete pom;
  92.  return a;
  93. }
  94. seznam::~seznam()
  95. {
  96.  prvek *pom = prvni;
  97.  while(pom)
  98.  {
  99.   prvni = prvni->dalsi;
  100.   delete pom;
  101.   pom = prvni;
  102.  }
  103. }
  104. seznam::Iterator& seznam::Iterator::operator++()
  105. {
  106.  if(!p) throw exception();
  107.  if(p->dalsi) p = p->dalsi;
  108.  return *this;
  109. }
  110.  
  111.  
  112. T& seznam::Iterator::operator*()
  113. {
  114.  if(!p) throw exception();
  115.  return p->data;
  116. }
  117.  
  118. // Sablona funkce pro trideni primym vyberem
  119. // verze pro starsi prekladace, kde je sablona vnorena 
  120. // do pomocne struktury, aby mohla mit i parametry, ktere nepouzijeme
  121. // jako typ parametru funkce
  122. template<class ITER, class Typ>
  123. struct Pom{ 
  124.   static void sort(ITER beg, ITER end)
  125.   {
  126.    for(ITER i = beg; i != end; ++i)
  127.    {
  128.      ITER ix = i; // Prvni prvek v prohledavanem useku
  129.      for(ITER u = i; u != end; ++u) // Projdi usek
  130.        if(*u < *ix) ix = u; // Zapamatuj si nejmensi
  131.      if(ix != i)// Neni-li to prvni, prohod s prvnim v useku (*i)
  132.      {
  133.         Typ x = *i;
  134.         *i = *ix;
  135.         *ix = x;
  136.      }
  137.    }
  138.   }
  139. };
  140.  
  141. // Totez, ale pro nove prekladace
  142. // Pouzivate-li starsi prekladac, nasledujici sablonu odstrante
  143. template<class ITER, class Typ>
  144. void sort(ITER beg, ITER end)
  145. {
  146.  for(ITER i = beg; i != end; ++i)
  147.  {
  148.    ITER ix = i; // Prvni prvek v prohledavanem useku
  149.    for(ITER u = i; u != end; ++u) // Projdi usek
  150.      if(*u < *ix) ix = u; // Zapamatuj si nejmensi
  151.    if(ix != i) // Neni-li to prvni, prohod s prvnim v useku (*i)
  152.    {
  153.       Typ x = *i;
  154.       *i = *ix;
  155.       *ix = x;
  156.    }
  157.  }
  158. }
  159. // Az po tento komentar odstrante, mate-li starsi prekladac,
  160. // ktery nepodporuje pripojovani parametru sablony v lomenych
  161. // zavorkach ke jmenu funkce
  162.  
  163. seznam::Iterator seznam::Najdi(T co)
  164. {
  165.  Iterator i(prvni);
  166.  zarazka -> data = co;
  167.  while(*i != co)++i;
  168.  return i;
  169. }
  170.  
  171. // A nekolk prikladu pouziti
  172. void main(){
  173.   seznam S;
  174. // Tady se nic nestane, takov² prvek v seznamu neexistuije
  175.   seznam::Iterator x = S.Najdi(11);
  176.   ++x;
  177.   clrscr();
  178. // Napl≥ seznam nßhodn²mi Φφsly
  179.   for (int i = 0; i < N; i++)
  180.     S.VlozNaKonec(rand());
  181.  
  182. // VypiÜ ho
  183.   for(seznam::Iterator I = S.begin(); I != S.end(); ++I)
  184.   cout << *I << endl;
  185.  
  186. // Najdi prvek a pokud tam je, zv∞tÜi ho o 100
  187.   seznam::Iterator k = S.Najdi(7117);
  188.   if(k != S.end())
  189.     *k += 100;
  190.   cout << "================" << endl;
  191.  
  192. // set°i∩ pole a seznam
  193. /* Pro starÜφ p°ekladaΦe
  194.   Pom<int*, int>::sort(A, &A[N]);
  195.   Pom<seznam::Iterator, int>::sort(S.begin(), S.end());
  196. */
  197.   sort<int*, int>(A, &A[N]);
  198.   sort<seznam::Iterator, int>(S.begin(), S.end());
  199.  
  200. // VypiÜ seznam
  201.   for(seznam::Iterator I(S.begin()); I != S.end(); ++I)
  202.   cout << *I << endl;
  203.  
  204. }