Ohjelmointi 2 2006/ 8.5
Demo C2 vastauksia
1. Linja-auto
// bussi.cpp
// Esimerkki yksinkertaisesta luokasta
#include <iostream.h>
#include <iomanip.h>
class cLinjaAuto {
int matkustajia;
int paikkoja;
public:
cLinjaAuto(int apaikkoja=50) { paikkoja = apaikkoja; matkustajia = 0; }
int lisaa(int m) {
matkustajia += m;
if ( matkustajia > paikkoja ) {
int yli = matkustajia-paikkoja;
matkustajia = paikkoja;
return yli;
}
return 0;
}
int vahenna(int m) {
matkustajia -= m;
if ( matkustajia < 0 ) {
int vajaa = matkustajia;
matkustajia = 0;
return vajaa;
}
return 0;
}
int tilaa() const { return paikkoja - matkustajia; }
int Matkustajia() const { return matkustajia; }
ostream &tulosta(ostream &os=cout) {
os << "Bussiin mahtuu: " << setw(2) << paikkoja
<< ", matkustajia: " << setw(2) << matkustajia
<< ", tilaa: " << setw(2) << tilaa() << endl;
return os;
}
};
int main(void)
{
cLinjaAuto pikkubussi(10),isobussi(45);
pikkubussi.lisaa(4); pikkubussi.tulosta();
isobussi.lisaa(30); isobussi.tulosta();
int yli = pikkubussi.lisaa(15);
isobussi.lisaa(yli);
pikkubussi.tulosta(); isobussi.tulosta();
if ( isobussi.tilaa() ) cout << "Isoon bussiin mahtuu!" << endl;
int vajaa = pikkubussi.vahenna(12);
if ( vajaa < 0 ) cout << "Pikkubussissa ei edes ole näin montaa!" << endl;
return 0;
}
2. Kulkunevot perinnällä
// kulku2.cpp
// Lentsikka ja laiva perinnän avulla
// vl 23.4.1996, muutos: 25.2.2001 const char * => string
#include <iostream.h>
#include <string>
class cKulkuneuvo {
string nimi;
int matkustajia;
double nopeus;
public:
cKulkuneuvo(const string &n, int mat, double nop) :
nimi(n), matkustajia(mat), nopeus(nop) {;}
virtual string vekotin() const { return "Kulkuneuvo"; }
virtual void tulosta(ostream &os=cout) const {
os << vekotin() << endl;
os << " Nimi: " << nimi << endl;
os << " Matkustajia: " << matkustajia << endl;
os << " Nopeus: " << nopeus << " km/h" << endl;
}
};
class cLentokone : public cKulkuneuvo {
double lentokorkeus;
public:
cLentokone(const string &n, int mat, double nop, double kork) :
cKulkuneuvo(n,mat,nop), lentokorkeus(kork) {;}
virtual string vekotin() const { return "Lentokone"; }
virtual void tulosta(ostream &os=cout) const {
cKulkuneuvo::tulosta(os);
os << " Lentokorkeus " << lentokorkeus << " m " << endl;
}
};
class cLaiva : public cKulkuneuvo {
public:
cLaiva(const string &n, int mat, double nop) :
cKulkuneuvo(n,mat,nop) {;}
virtual string vekotin() const { return "Laiva"; }
};
int main(void)
{
cLentokone dc3("DC3",25,320,4500);
cLaiva fennia("Fennia",1200,40);
dc3.tulosta();
fennia.tulosta();
return 0;
}
3. Koostaminen
/* valuuttsk.cpp */
...
//---------------------------------------------------------------------------
// Koostetaan list-luokasta
// cValuutat, johon lisataan muutama valuutoille ominainen lisapiirre
class cValuutat {
list<cValuutta> alkiot;
static string virhe;
public:
cValuutat(int koko=0) : alkiot() { ; }
const string &valuutta(const char *val) const {
list<cValuutta>::const_iterator i = find(alkiot.begin(),alkiot.end(),cValuutta(1.0,val));
if ( i != alkiot.end() ) return i->Valuutta();
return virhe;
}
double kerroin(const cValuutta &val) const {
list<cValuutta>::const_iterator i = find(alkiot.begin(),alkiot.end(),val);
if ( i != alkiot.end() ) return i->Maara();
return 1.0;
}
const string &mk() const { return alkiot.begin()->Valuutta(); }
int lue(const string &nimi) {
ifstream f(nimi.c_str()); if ( !f ) return 1;
string rivi;
while ( getline(f,rivi) ) { alkiot.push_back(cValuutta(rivi)); }
return 0;
}
ostream &tulosta(ostream &os) const {
copy(alkiot.begin(),alkiot.end(),ostream_iterator<cValuutta>(os,"\n"));
return os;
}
};
ostream &operator<<(ostream &os, const cValuutat &v) { return v.tulosta(os); }
4&5. Dynaaminen C++ -taulukko
Tehtävä 5 olikin vahingossa jo tehty :-)
// taul2.cpp
// Malli dynaamisesta taulukosta /vl-96
#include <iostream.h>
#include <iomanip.h>
int poista(int taulukko[],int lkm,int n) /* indekseillä */
{
int luku,kirj;
for (luku=0,kirj=0; luku<lkm; luku++)
if ( taulukko[luku] != n )
taulukko[kirj++] = taulukko[luku];
return kirj;
}
class cTaulukko {
int max_koko;
int lkm;
int *alkiot;
public:
int varaa(int koko) {
lkm = 0; max_koko = 0;
if ( koko <= 0 ) return 0;
alkiot = new int[koko];
if ( alkiot ) max_koko = koko;
return max_koko == 0;
}
void vapauta() { if ( max_koko > 0 ) delete [] alkiot; max_koko = 0; }
cTaulukko(int koko=0) { varaa(koko); }
cTaulukko(const cTaulukko &luvut) : max_koko(0) { sijoita(luvut); } // Copy Constructor
~cTaulukko() { vapauta(); }
int lisaa(int n) {
if ( lkm >= max_koko ) return 1;
alkiot[lkm++] = n;
return 0;
}
int poista(int n) { // kutsutaan valmista kun sellainen tuli tehtya
lkm = ::poista(alkiot,lkm,n); // ::poista tarkoittaa että kuts. glob.
return lkm;
}
ostream &tulosta(ostream &os) const;
cTaulukko &sijoita(const cTaulukko &luvut);
cTaulukko &operator=(const cTaulukko &luvut) { return sijoita(luvut); }
};
cTaulukko &cTaulukko::sijoita(const cTaulukko &luvut)
{
if ( this == &luvut ) return *this;
if ( max_koko != luvut.max_koko ) {
vapauta(); varaa(luvut.max_koko);
}
lkm = 0;
for (int i=0; i<luvut.lkm; i++)
lisaa(luvut.alkiot[i]);
return *this;
}
ostream &cTaulukko::tulosta(ostream &os) const
{
for (int i=0; i<lkm; i++)
os << alkiot[i] << " ";
return os;
}
ostream &operator<<(ostream &os,const cTaulukko &taul) {
return taul.tulosta(os);
}
int main(void)
{
cTaulukko luvut(7);
luvut.lisaa(0); luvut.lisaa(2); luvut.lisaa(2); luvut.lisaa(4); luvut.lisaa(2);
cout << luvut << endl; // 0 2 4 2 2
cTaulukko taul;
taul.sijoita(luvut); // tai jopa taul = luvut;
cout << taul << endl; // 0 2 4 2 2
taul.poista(2);
cout << taul << endl; // 0 4
return 0;
}
6&7 Lajittele nimet
// henkilots.cpp
// Ohjelmalla luetaan ihmisten nimia ja lajitellaan ne.
// Nimet sailytetaan muodossa etunimi sukunimi, mutta
// lajitellaan sukunimi etunimi perusteella
// Tietorakenteen toteutus STL:n vector-luokalla
// Projektiin lisaksi: mjonot.c
// Vesa Lappalainen 25.4.1999
#include <iostream>
#include <fstream>
#include <string>
#include "mjonotpp.h"
using std::string;
using std::ostream;
using std::ifstream;
using std::ofstream;
using std::cin;
using std::cout;
using std::endl;
class cHenkilo {
string nimi;
string avain;
public:
void sijoita(const string &s) {
nimi = s;
string suku(s);
avain = erota(suku,' ');
if ( suku != "" ) avain = suku + ' ' + avain;
jono_isoksi(avain);
}
cHenkilo(const string &s) { sijoita(s); }
void operator=(const string &s) { sijoita(s); }
ostream &tulosta(ostream &os) const { os << nimi; return os;}
int vertaa(const cHenkilo &h) const { return avain.compare(h.avain); }
int operator<(const cHenkilo &h) const { return vertaa(h) < 0; }
};
ostream &operator<<(ostream &os, const cHenkilo &h) { return h.tulosta(os); }
#include <vector>
#include <iterator>
#include <algorithm>
using std::vector;
using std::ostream_iterator;
using std::sort;
class cHenkilot {
vector<cHenkilo> alkiot;
public:
cHenkilot() : alkiot() {}
int lue(const string &nimi) {
ifstream f(nimi.c_str()); if ( !f ) return 1;
string rivi;
while ( getline(f,rivi) ) { alkiot.push_back(cHenkilo(rivi)); }
return 0;
}
ostream &tulosta(ostream &os) const {
copy(alkiot.begin(),alkiot.end(),ostream_iterator<cHenkilo>(os,"\n"));
return os;
}
int kirjoita(const string &nimi) const {
ofstream f(nimi.c_str()); if ( !f ) return 1;
tulosta(f);
return 0;
}
int kysy_uusia() {
string s;
while ( 1 ) {
cout << "Anna nimi >"; getline(cin,s);
if ( s == "" ) return 0;
alkiot.push_back(cHenkilo(s));
}
}
void lajittele() {
sort(alkiot.begin(),alkiot.end());
}
};
//---------------------------------------------------------------------------
int main(void)
{
cHenkilot hlot;
hlot.lue("henkilot.dat");
cout << "-----------------------------------------" << endl;
cout << "Ennen lis,yst,:" << endl;
hlot.tulosta(cout);
cout << "-----------------------------------------" << endl;
hlot.kysy_uusia();
cout << "-----------------------------------------" << endl;
cout << "Ennen lajittelua:" << endl;
hlot.tulosta(cout);
cout << "-----------------------------------------" << endl;
cout << "Lajittelun j,lkeen:" << endl;
hlot.lajittele();
hlot.tulosta(cout);
cout << "-----------------------------------------" << endl;
hlot.kirjoita("henkilot.dat");
return 0;
}
8&9&10 Pasianssi
/*
** pasi3.cpp
**
** Ohjelmalla pelataan yksinkertaista pasianssia:
** 0. pakka sotketaan
** 1. ruvetaan laskemaan kädessä olevia kortteja pöydälle ja
** samalla lasketaan 1 2 3 4 .. 13 1 2 3 ..
** 2. Jos laskuissa osutaan saman kortin kohdalle, joka laiteaan
** pöydälle, EI PELI MENE LÄPI
**
** Vesa Lappalainen 28.11.1991
**
** Muutettu olio-ohjelmaksi
** Vesa Lappalainen 1996
*/
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include "streampr.h"
using std::cout;
using std::setw;
using std::endl;
using std::rand;
using std::randomize;
#include "dosout.h"
/*************************************************************************/
class cHisto {
int lkm;
long *esiintymat;
cHisto(const cHisto &) { }
void operator=(const cHisto &) { }
public:
cHisto(int n);
~cHisto();
int lisaa(int i);
long etsi_max() const;
int piirra() const;
};
cHisto::~cHisto()
{
if ( lkm ) delete [] esiintymat;
lkm = 0; esiintymat = NULL;
}
cHisto::cHisto(int n)
{
lkm = 0;
if ( n <= 0 ) return;
esiintymat = new long[n];
if ( esiintymat == NULL ) return;
lkm = n;
for (int i=0; i<lkm; i++) esiintymat[i] = 0;
return;
}
int cHisto::lisaa(int i)
{
if ( i < 0 || lkm <= i ) return 1;
esiintymat[i]++;
return 0;
}
long cHisto::etsi_max() const
{
int i; long m;
if ( lkm == 0 ) return 0;
m = esiintymat[0];
for ( i=0; i<lkm; i++)
if ( esiintymat[i] > m )
m = esiintymat[i];
return m;
}
int cHisto::piirra() const
{
int i,j,pituus;
long pisin = etsi_max();
if ( pisin == 0 ) return 1;
for (i=0; i<24 /*lkm*/; i++) {
cout << setw(3) << i << ": ";
pituus = 60.0*esiintymat[i]/pisin;
for (j=0; j<pituus; j++) cout << "*";
cout << endl;
}
return 0;
}
/*************************************************************************/
typedef enum {
Hertta,Pata,Ruutu,Risti
} eMaa;
class cKortti {
eMaa maa;
int arvo;
public:
cKortti() { set(Hertta,1); }
eMaa getMaa() { return maa; }
void setMaa(eMaa m) { maa = m; }
int getArvo() { return arvo; }
void setArvo(int a) { arvo = a; } // Lisää tarkistukset
void set(eMaa m, int a) { setMaa(m); setArvo(a); }
};
class cPakka {
cKortti kortit[52];
public:
cPakka() { sotke(); }
int pelaa_peli();
void sotke();
void jarjesta();
};
void cPakka::jarjesta()
{
eMaa m;
int a,i=0;
for (m = Hertta; m <= Risti; m = (eMaa)(m+1))
for (a = 1; a <= 13; a++) {
kortit[i++].set(m,a);
}
}
void cPakka::sotke()
{
int i,k;
cKortti apu;
jarjesta();
for ( i=51; i>=0; i-- ) {
k = rand() % (i+1); /* Satunnaisluku välille [0-i] */
apu = kortit[i];
kortit[i] = kortit[k];
kortit[k] = apu;
}
}
int cPakka::pelaa_peli()
{
int k;
for (k=0; k<52; k++) {
if ( kortit[k].getArvo() == (k%13)+1 ) return k+1;
}
return 0;
}
/*************************************************************************/
int main(void)
{
int p,lapi=0;
long peleja=0;
cPakka pakka;
randomize();
cHisto histo(53);
cStreamPre(cout,2);
while (lapi<100) {
pakka.sotke();
p = pakka.pelaa_peli();
peleja++;
histo.lisaa(p);
if ( p==0 ) lapi++;
if ( !(peleja % 1000) ) {
cout << "Peli " << setw(5) << peleja
<< ": Läpi " << setw(3) << lapi << " kertaa."
<< " Tn: " << setw(5) << 100.0*lapi/peleja << "%" << endl;
}
}
histo.piirra();
return 0;
}