12. Jäsenrekisterin runko
*
tietorakenteen valinta
Emme vielä täysin osaa tehdä edes runkoa
jäsenrekisteriohjelmaamme, mutta esitämme tästä huolimatta
jonkinlaisen toimivan rungon ohjelmalistauksen. Koodista on poistettu
kommentit, jotta listaus mahtuisi tässä vaiheessa
lyhyempään tilaan. Koodissa tulee lukuisia vielä
käsittelemättömiä osia, joita käsittelemme tarkemmin
myöhemmin. Samoin etsimme myöhemmin sopivan tavan kommentoida
aliohjelmia.
Rungon tarkoituksena on tarjota näkyväksi ne toiminnot, jotka
ohjelman suunnitelmassa päätettiin tehdä. Samoin tavoitteena on
testata valitun tietorakenteen toimivuus. Jatkossa toimintoja
lisätään tähän runkoon.
Tämä runko ei tietenkään ole syntynyt kerralla, vaan
alkuperäinen runko on ollut esimerkiksi ilman tietorakenteita (vrt.
menut.05\kerho.cpp)
Minkälaisen
tietotyypin voisimme valita? Vaihtoehtoja tulee ehkä lähes
yhtäpaljon kuin ohjelmoijiakin on. Voimme kuitenkin vertailla
eräiden rakenteiden etuja ja haittoja. Jos mahdollista, tietorakenteiden
tulisi olla yhtenäinen tehdyn oliosuunnitelman kanssa. Seuraavista
ehdotuksista mikään ei ole ristiriidassa edellisessä luvussa
tehdyn oliosuunnitelman kanssa. Vasta kun valitaan harrastusten talletustapaa,
joudumme valinnan eteen.
Lähdemme siitä ajatuksesta, että koko käsiteltävä
aineisto on kerralla keskusmuistissa. Voisimme tietenkin operoida myös
suoraan levylle, mutta oppimisen tässä vaiheessa voi seuraava
ratkaisu olla helpompi:
lue tiedosto muistiin
käsittele aineistoa muistissa
talleta aineisto takaisin levylle
Taulukko
on kiinteä tietorakenne, jota luotaessa täytyy jo tietää
monelleko ihmiselle varaamme tilaa. Tässä tulee äkkiä
varattua tilaa joko liikaa, jolloin tila ei riitä muille toiminnoille, tai
liian vähän, jolloin kaikki henkilöt eivät mahdu
rekisteriin. Esimerkissämme olemme varanneet n. 300 tavua/henkilö.
Tilan varaaminen sadalle henkilölle veisi jo 30000 tavua. Usein sata ei
edes riitä!
Kuva 12.4 Taulukko
Linkitetty
lista on rakenne, jossa meillä on tieto vain listan 1. alkiosta.
Tämän jälkeen kukin alkio tietää itseään
seuraavan alkion, kunnes listan viimeinen alkio ei enää osoita
minnekään.
Kuva 12.5 Linkitetty lista
Listan hyvänä puolena on se, ettei etukäteen tarvita
mitään tietoa alkioiden lukumäärästä. Alkioita
voidaan lisätä listaan joko alkuun, keskelle tai loppuun niin kauan
kuin muistia riittää.
Oppimisen tässä vaiheessa kuitenkin linkitetyn listan
käsittelyalgoritmit (lisäys, poisto, lajittelu jne..) saattavat olla
liian työläitä.
Mikäli rakennamme ohjelman huolella, ei tietorakenteen vaihtaminen
jälkeen päinkään ole mahdoton tehtävä.
Tätä auttaa vielä aikaisemmin tekemämme valinta
käyttää abstraktia rajapintaa (lisää, poista, etsi)
tietorakenneluokan (cKerho tai cJasenet) ja
käyttöliittymän (cNaytto) välillä.
Valitsemme
tähän toteutukseen tietorakenteeksi sekarakenteen:
Siis perusrakenteena meillä on cKerho- tyyppi, joka
pitää sisällään kerhon perustiedot. Kerhosta on
osoitin taulukkoon, jossa on osoittimet varsinaisiin henkilöiden tietoihin
(cJasen).
Henkilöiden tiedoille varattua tilaa ei ole olemassa ennenkuin sitä
tarvitaan. Siis varataan kullekin kerhoon lisättävälle
henkilölle hänen tiedoilleen tarvittava uusi n. 300 tavun
"möykky" lisäyksen yhteydessä.
Osoitintaulukkoon sijoitetaan sitten vastaavaan paikkaan sen muistiosoitteen
arvo, josta henkilölle tarvittava tila saatiin varattua.
Tässäkin rakenteessa on se huono puoli, että osoitintaulukon
koko pitää päättää ennen kuin sinne voidaan
sijoittaa osoitteita. Yksi osoite vie kuitenkin enimmilläänkin tilaa
4 tavua, joten kiinteää tilan varausta esim. 1000 henkilön
taulukossa tulee vain 4000 tavua.
Hyvinä puolina rakenteessa on sen suhteellisen helppo käsittely
sekä lisäyksen, poiston että lajittelun tapauksessa.
Kuva 12.6 Tietorakenne kun kerho tallettaa jäsenet
- Kirjoita algoritmi henkilön lisäämiseksi rakenteeseen.
- Kirjoita algoritmi tietyn henkilön etsimiseksi (vaikkapa nimellä).
- Kirjoita algoritmi löydetyn henkilön (miten löytö
kannattaa säilyttää?) poistamiseksi rakenteesta.
- Kirjoita algoritmi rakenteen lajittelemiseksi aakkosjärjestykseen.
Mitä lajittelussa kannattaa vaihdella?
Ohjelmalistaus
löytyy listausmonisteesta tiedostosta
- runko.1\kerho.cpp
Jos
halutaan tallettaa myös kullekin jäsenelle vaihteleva
määrä harrastuksia, on jälleen mahdollisuuksia useita.
Tietorakennetta valittaessa voidaan käyttää samaa kriteeriä
kuin tiedostoakin valittaessa. Välttämätöntä
tämä ei kuitenkaan ole, vaan voidaan sisäisesti tietysti
käyttää myös erilaista rakennetta kuin ulkoisesti.
Jos tiedoston muoto on sellainen että harrastukset on lueteltu
jäsenen tietojen yhteydessä, kannattaa tietorakennekin valita
vastaavasti.
Ankka Aku |010245-123U|Ankkakuja 6 |12345 |ANKKALINNA |12-12324 | |
- kalastus | 1955 | 20
- laiskottelu | 1950 | 20
- työn pakoilu | 1952 | 40
Susi Sepe |020347-123T| |12555 |Takametsä | | |
- possujen jahtaaminen | 1954 | 20
- kelmien kerho | 1962 | 2
Ponteva Veli |030455-3333| |12555 |Takametsä | | |
- susiansojen rakentaminen | 1956 | 15
Nyt tietorakenne voisi olla tilanteesta riippuen mikä tahansa edellä
esitetyistä siten, että kerhosta alkava rakenne toistuu
jäsenen kohdalla.
Esimerkiksi linkitetty lista:
Kuva 12.7 Harrastukset linkitettynä listana
Jos tiedot on talletettu relaatiomallin mukaan, voi olla kannattavaa tehdä
myös sisäinen tietorakenne vastaavaksi. Vaikka jatkossa emme
toteutakaan kerhoon vielä harrastuksia, teemme tietorakenteen ja oliot
sellaisiksi, että harrastusten käsittely jälkeenpäin olisi
mahdollisimman helppoa.
Toteutettavaa ohjelmaa ajatellen tästä valinnasta seuraa yksi
byrokratiaporras (cKerho <-> cJasenet) lisää, joka
aluksi saattaa tuntua turhalta. Valinta maksaa itseään takaisin
vasta ongelman monimutkaistuessa. Tähän samaan
monimutkaistumisongelmaan tulemme törmäämään
jatkossakin. Yksinkertaisin mahdollisuus, jolla vaadittu toimenpide juuri ja
juuri voidaan suorittaa, johtaa usein jatkoa ajatellen umpikujaan.
- Kirjoita algoritmi uuden harrastuksen lisäämiseksi. (Ks. alla
oleva kuva)
- Kirjoita algoritmi, joka vastaa kysymykseen "Mitä henkilö N
harrastaa?"
- Kirjoita algoritmi, joka vastaa kysymykseen: "Ketkä harrastavat
harrastusta H?".
- Kirjoita algoritmi harrastuksen poistamiseksi.
- Kirjoita algoritmi, joka poistaa jäsenen jonkin nimi on N.
- Kirjoita algoritmi, joka poistaa "roskaharrastukset", eli ne harrastukset,
joille ei löydy "omistajaa". Tällaiseen tilanteeseen
hyvässä ohjelmassa ei tietenkään koskaan
päädytä.
- Jos harrastusten nimet ovat kovin pitkiä ja harrastuksista talletetaan
vielä kuhunkin harrastukseen liittyvää lisätietoa, niin
edellä mainittu rakenne käy tehottomaksi heti kun löytyy useita
saman lajin harrastajia. Esitä ratkaisu, jossa hukkatilaa (mm. saman
harrastuksen nimen toistamista) ei esiinny, mutta jolla voidaan tehdä
kaikki samat tehtävät, kuin esitetyllä ratkaisulla.
Kuva 12.8 Harrastukset relaation avulla
Ohjelmalistaus,
jossa harrastuksetkin ovat mukana, löytyy listausmonisteesta tiedostosta
- runko.1\kerhohar.
-