Demo 2 vastauksia


1. 2-suuntainen lista (Tehtävä 2.36_1)

	/* teht8_1.cpp M 2.30.1 */
	/*
	Tehtäviä 1) Peri luokasta luokka list2, joka on kaksisuuntainen ja
	            jossa voidaan siis liikkua kumpaankin suuntaan.
	*/
	
	#include <iostream.h>
	
	inline int inside(int a,int x,int b) // x välille [a,b], jos b<a niin a
	  { return b < a ? a : x < a ? a : x < b ? x : b; }
	
	#define MAX_ELEM 100
	
	#define TYPE char
	
	...
	
	class list2 : public list {
	public:
	  list2() : list() {};
	  int  backward()  { --cursor;   return out();                 }
	  TYPE previous()  { backward(); return current();             }
	};
	
	
	/****************************************************************************/
	int main(void)
	{
	  list2 lc; lc.add('a'); lc.add('b'); lc.add('c'); lc.add('d');
	
	  for (lc.toend(); !lc.out(); lc.backward() )
	    cout << lc.current() << " ";
	
	  return 0;

	}

2. Linkitetty lista (Tehtävä 2.36_2)

	/* teht8_2.cpp M 2.30.2 */
	/*
	         2) Toteuta list "oikeana" dynaamisena listana.
	*/
	
	#include <iostream.h>
	
	#define TYPE char

	class list;

	
	class elem {
	  friend list;
	  TYPE data;
	  elem *next_elem;
	  elem(TYPE d)  { data = d; next_elem = NULL; }
	  int add(elem *n) { next_elem = n; return 0; }
	};
	
	

	class list {

	protected:
	  elem *first_elem;
	  elem *last_elem;
	  elem *cursor;          // Sijainti listassa
	  TYPE out_data;
	  int no_elem()    { first_elem = last_elem = cursor = NULL; out_data = 0;
	                     return 0;                                               }
	public:
	  int delete_all();
	  list()           { no_elem();                                              }
	  ~list()          { delete_all();                                           }
	
	  int  out()       { return ( cursor == NULL );                              }
	  int  tobegin()   { cursor = first_elem;   return out();                    }
	  int  forward()   { if ( !cursor ) return 1;
	                     out_data = cursor->data;
	                     cursor = cursor->next_elem; return 0;                   }
	  int  toend()     { cursor = last_elem; return out();                       }
	  TYPE current()   { return cursor ? cursor->data : out_data;                }
	  TYPE first()     { tobegin(); return current();                            }
	  TYPE next()      { forward(); return current();                            }
	  TYPE last()      { toend();   return current();                            }
	  int  empty()     { return ( first_elem == NULL );                          }
	  int  add(TYPE p) { elem *n = new elem(p);
	                     if ( !n ) return 1;
	                     if ( first_elem ) last_elem->add(n);
	                     else first_elem = n;
	                     last_elem = n; return 0;
	                   }

	}; /* list */

	
	int list::delete_all()
	{
	  elem *e;
	  tobegin();
	  while ( cursor ) { e = cursor; forward(); delete e; }
	  return no_elem();
	}
	

	#define VIIVA "------------------------------------------------------------\n"

	/****************************************************************************/
	int main(void)
	{
	  cout << VIIVA;
	
	  list lc; lc.add('a'); lc.add('b'); lc.add('c'); lc.add('d');
	
	  for (char c=lc.first(); !lc.out(); c=lc.next() )
	    cout << c << " ";
	
	  cout << c << "\n" << VIIVA;
	
	  for (lc.tobegin(); !lc.out(); lc.forward() )
	    cout << lc.current() << " ";
	
	  cout << lc.current() << "\n" << VIIVA;
	
	  return 0;

	}

3. 2-suuntainen linkitetty lista (Tehtävä 2.37_3)

	/* teht8_3.cpp M 2.30.3 */
	/*
	         3) Peri tehtävän 2 listasta 2-suuntainen lista.
	            Onnistuuko kunnolla? Ei ilman templatea!
	*/
	
	#include <iostream.h>
	
	template <class TYPE>
	class elem {
	public:
	  TYPE data;
	  elem *next_elem;
	  virtual int add(elem *n) { next_elem = n; return 0; }
	  elem(TYPE &d)    { data = d; next_elem = NULL; }

	};

	
	
	template <class TYPE,class ELEM>
	class base_list {
	protected:
	  ELEM *first_elem;
	  ELEM *last_elem;
	  elem<TYPE> *cursor;          // Sijainti listassa
	  TYPE out_data;
	  int no_elem()    { cursor = first_elem = last_elem = NULL;

	                     out_data = 0; return 0;                                 }

	public:
	  int delete_all();
	  base_list()      { no_elem();                                              }
	  ~base_list()     { delete_all();                                           }
	
	  int  out()       { return ( cursor == NULL );                              }
	  int  tobegin()   { cursor = first_elem;   return out();                    }
	  int  forward()   { if ( !cursor ) return 1;
	                     out_data = cursor->data;
	                     cursor = cursor->next_elem; return 0;                   }
	  int  toend()     { cursor = last_elem; return out();                       }
	  const TYPE &current()   { return cursor ? cursor->data : out_data;         }
	  const TYPE &first()     { tobegin(); return current();                     }
	  const TYPE &next()      { forward(); return current();                     }
	  const TYPE &last()      { toend();   return current();                     }
	  int  empty()     { return ( first_elem == NULL );                          }
	  int  add(TYPE p) { ELEM *n = new ELEM(p);
	                     if ( !n ) return 1;
	                     if ( first_elem ) last_elem->add(n);
	                     else first_elem = n;
	                     last_elem = n; return 0;
	                   }

	}; /* base_list<TYPE,ELEM> */

	
	template <class TYPE,class ELEM>
	int base_list<TYPE,ELEM>::delete_all()
	{
	  elem<TYPE> *e;
	  tobegin();
	  while ( cursor ) { e = cursor; forward(); delete e; }
	  return no_elem();

	}

	
	/****************************************************************************/
	template <class TYPE>
	class single_elem : public elem<TYPE> {
	public:
	  single_elem(TYPE &d) : elem<TYPE>(d) {};

	}

	
	template <class TYPE>
	class list : public base_list<TYPE,single_elem<TYPE> > {
	public:
	  list() : base_list<TYPE,single_elem<TYPE> >  () {};

	};

	
	/****************************************************************************/
	template <class TYPE>
	class double_elem : public elem<TYPE>  {
	public:
	  double_elem *previous_elem;
	  double_elem(TYPE &d) : elem<TYPE>(d) { previous_elem = NULL;};
	  int add(elem<TYPE> *n) {
	    ((double_elem<TYPE> *)n)->previous_elem = this; next_elem = n; return 0; }

	}

	
	template <class TYPE>
	class dlist : public base_list<TYPE,double_elem<TYPE> > {
	public:
	  dlist() : base_list<TYPE,double_elem<TYPE> >  () {};
	  int  backward()  { if ( !cursor ) return 1;
	                     out_data = cursor->data;
	                     cursor = ((double_elem<TYPE> *)cursor)->previous_elem;
	                     return 0;                                               }
	  const TYPE &previous() { backward(); return current();                     }

	};

	
	#define VIIVA "------------------------------------------------------------\n"
	/****************************************************************************/
	int main(void)
	{
	  cout << VIIVA;
	
	  dlist<char> lc; lc.add('a'); lc.add('b'); lc.add('c'); lc.add('d');
	
	  for (char c=lc.first(); !lc.out(); c=lc.next() )
	    cout << c << " ";
	
	  cout << c << "\n" << VIIVA;
	
	  for (lc.tobegin(); !lc.out(); lc.forward() )
	    cout << lc.current() << " ";
	
	  cout << lc.current() << "\n" << VIIVA;
	#if 1
	  for (c=lc.last(); !lc.out(); c=lc.previous() )
	    cout << c << " ";
	
	  cout << c << "\n" << VIIVA;
	
	  for (lc.toend(); !lc.out(); lc.backward() )
	    cout << lc.current() << " ";
	
	  cout << lc.current() << "\n" << VIIVA;
	#endif
	  return 0;

	}

4. "Virheen" käsittely hävittäjän avulla (Tehtävä 2.38)

	/* Teht9  M 2.32 */
	#include <iostream.h>
	#include <stdio.h>
	#include <string.h>
	
	class tiedosto {
	  FILE *f;
	  char nimi[50];     // tiedoston nimi
	public:
	  tiedosto(char *s) { strncpy(nimi,s,sizeof(nimi)); f = NULL;                }
	  int avaa()        { f = fopen(nimi,"r"); return (f != NULL) ? 0 : 1;       }
	  int lue()         { int c = fgetc(f); return c != EOF ? c : 0;             }
	  int sulje()       { if ( f ) fclose(f); return 0;                          }
	  ~tiedosto()       { sulje();                                               }
	};
	
	
	int tiedostot(char *na, char *nb, char *nc)
	{
	  tiedosto a(na), b(nb), c(nc);
	  if ( a.avaa() ) return -1;
	  if ( b.avaa() ) return -2;
	  if ( c.avaa() ) return -3;
	  return  a.lue() + b.lue() + c.lue();
	}
	
	int main(void)
	{
	  int k = tiedostot("t1","t2","t3");
	  cout << "Funktio palautti " << k << '\n'; 
	
	  return 0;
	}

	

5. "Virheen" käsittely poikkeusten avulla (Tehtävä 2.39)

	/* Teht9b  M 2.33 */
	#include <iostream.h>
	#include <stdio.h>
	#include <string.h>

	

	class tiedosto {
	  FILE *f;
	  char nimi[13];     // tiedoston nimi
	  int nro;           // tiedoston numero
	public:
	  tiedosto(char *s,int k) { strncpy(nimi,s,sizeof(nimi));
	                            f = NULL; nro = k; avaa();                       }
	  int avaa() {
	    f = fopen(nimi,"r");
	    if (f == NULL) throw int(nro);
	    return 0;
	  }
	  int lue()         { int c = fgetc(f); return c != EOF ? c : 0;             }
	  int sulje()       { if ( f ) fclose(f); return 0;                          }
	  ~tiedosto()       { sulje();                                               }

	};

	
	int tiedostot(char *na, char *nb, char *nc)
	{
	  try {
	    tiedosto a(na,-1), b(nb,-2), c(nc,-3);
	    return  a.lue() + b.lue() + c.lue();
	  }
	  catch ( int n ) { return n; }

	}

	
	int main(void)
	{
	  int k = tiedostot("t1","t2","t3");
	  cout << "Funktio palautti " << k << '\n';
	
	  return 0;
	}
	



Last update: ma 20.09.1999 8:04