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 ¤t() { 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;
}