PR1ET5: Massiivid

Labori materjal

Esitamisele kuuluvad ülesanded

Selle nädala tunnitöö on jupitatud kaheks osaks. Alguses lahenda esimene osa ja esita oma lahendus. Seejärel laienda lahendust teise osaga ning esita oma lahendus uuesti.  Baasülesandele on sel korral pakutud  2 laiendavat lisaülesannet.

Ülesanne 1 osa 1: ekstreemumite leidmine

Ülesande esimene osa on tunnis tehtud UML tegevusdiagrammi realisatsioon C programmikoodina. Esimeses osas pead sa kokku looma 4 funktsiooni lisaks main()  funktsioonile!

Lae alla ülesande aluskood: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/5_minmax_template.c

Nõuded
  • Esimene ülesande osa peab vastama tunnis tehtud UML tegevusdiagramile.
  • Ülesande lahendamiseks pead looma 4 funktsiooni. Funktsioonid on aluskoodis kirjeldatud kommentaaridena. Kirjuta oma funktsioon kohe kommentaari järgi. Lisa puuduvad elemendid nagu makrod, muutujate deklaratsioonid, funktsioonide prototüübid ja väljakutsed.
  • Klaviatuurilt loetakse 6 täisarvu, mis salvestatakse massiivi.
  • Sisestuse kulg peab olema kasutajale arusaadav, näidates mitmendat arvu parasjagu sisestatakse ning mitu kokku kasutajalt oodatakse.
  • Massiivist leitakse ja väljastatakse suurim sisestatud arv. Vähim arv tuleb leida funktsioonis, mis tagastab tulemuse. Tulemuse väljastus toimub main() funktsioonis.
  • Massiivist leitakse ja väljastatakse vähim sisestatud arv. Suurim arv tuleb leida funktsioonis, mis tagastab tulemuse. Tulemuse väljastus toimub main() funktsioonis.
  • Väljastatakse algselt sisestatud massiivi kõik liikmed. Väljastus loo eraldi funktsioonis.
Ülesande lahendamise juhend

NB! Enne funktsioonide loomist loe läbi aluskoodis olev funktsiooni kirjeldus ja veendu, et saad sellest aru (st mida funktsioon teeb, mis on selle parameetrid ja kas ning mida see funktsioon tagastab. Iga funktsioon tuleb realiseerida ettekirjutatud funktsiooni kommentaari järel.

  1. Alusta funktsiooni  ReadIntArray()  lahendamisest. See on esimene funktsioon kohe pärast main() funktsiooni. Sul tuleb kirjutada tsükkel, mille igal kordusel küsitakse kasutajalt väärtus ning seejärel loetakse see massiivi.
  2. Testimaks kas see töötab, pead selle funktsiooni välja kutsuma. Selleks pead esmalt massiivi deklareerima kus arve hoida. Seejärel kutsu funktsioon  ReadIntArray()  välja, andes talle kaasa loodud massiiv ning selle pikkus.
    Eeldusel, et pikkust kirjeldav makro nimi on NUM_CNT ja massiivi nimi on numbers , võiks selle funktsiooni väljakutse näha välja midagi sarnast: ReadIntArray(numbers, NUM_CNT);  Proovi nüüd kas massiivi arvude lugemine toimis.
  3. Veendumaks, et numbrid ka korrektselt loetud said peaksid massiivi sisu välja trükkima. Selleks realiseeri funktsioon PrintArray()   ja kutsu see välja main() funktsioonist. Sel korral pead tagastuse tüübi ja parameetrid ise valima. Kui funktsioon tehtud ja välja kutsutud, peaksid nägema oma massiivi sisestatud numbreid.
  4. Nüüd tuleb sul veel viimased kaks funktsiooni lõpetada. Mõlemad on kirjeldatud kommentaaridena aluskoodis. Lõpeta funktsioonid ja väljasta tulemused.
    NB! Tulemust tohid väljastada vaid main() funktsioonis. Min ja max väärtuste leidmiste funktsioonides väljastada tulemust ei tohi! Selleks pead tulemuse nendest funktsioonidest esmalt tagastama. 
Testimine

Test 1: min esimene, max viimane

Test 2: min viimane, max esimene

Test 3: Negatiivne min. Min ja max on massiivi keskel.

Ülesanne 1 osa 2: asukohtade ja korduste arvu leidmine

Ülesande esimeses osas leidsid massiivist ekstreemväärtused. Teises osas tuleb leida nende positsioonid ning mitu korda väärtused massiivis esinesid.

Nõuded
  • Kuva kõik positsioonid, kus asus massiivi suurem väärtus. Tulemus tuleb leida ja väljastada eraldi funktsioonis
  • Kuva kõik positsioonid, kus asus massiivi väikseim väärtus. Tulemus tuleb leida ja väljastada eraldi funktsioonis
  • Kuva mitu korda suurim ja suurim väärtus massiivis eksisteeris. Tulemus tuleb leida eraldi funktsioonis, tagastada ning seejärel väljastada main()  funktsioonis.
  • Kuvatavad positsioonid peavad olema vastavuses sisestusega.
Ülesande lahendamise juhend

Selle osa lahendamiseks pead looma kokku kaks funktsiooni. Mõlemad funktsioonid on kirjeldatud funktsiooni kommentaaridena. Kopeeri funktsiooni kommentaar enda koodi ja kirjuta lahendus selle järel

Esimene funktsioon väljastab eelnevalt leitud ekstreemumväärtuse kõik asukohad massiivis. Selle lahendamiseks pead looma tsükli, mis käib läbi kõik massiivi liikmed. Iga kord, kui massiivi liikme väärtus on sama kui sinu otsitav (nt minimaalne väärtus massiivis), pead väljastama ekraanile oma praeguse asukoha tsüklis (tsükli praeguse korduse väärtus on seotud massiivi positsiooniga). St kogu funktsioon sisaldab ühte tsüklit, ühte tingimuslauset ja ühte väljastuslauset – ongi kõik.

Loodavat funktsiooni pead korduvkasutama (st 2x välja kutsuma) nii minimaalse kui maksimaalse väärtuse asukohtade kuvamiseks! Tulemustele eelnev tekst (nt “Min value position(s)”) tuleks väljastada main() funktsioonis, enne selle funktsiooni väljakutset.

Kui funktsioon valmis, kontrolli, et see töötab enne kui lähed järgmist funktsiooni lahendama!

Teine funktsioon saab olema vägagi sarnane eelmisele. Sel korral aga peame loendama (st ühte täisarvulist muutujat suurendama sobilikul hetkel) väljastamise asemel. Väljastust selles funktsioonis teha ei tohi! Funktsioon peab oma tulemuse tagastama. Tulemus väljastatakse main() funktsioonis.

Testimine

Test 1: min ja max on ühekordsed

Test 2: min ja max korduvad

Lisaülesanne 1: Tulemuste leidmine massiivist

Selles osas leiame kolm täiendavat tulemust massiivist

Nõuded
  • Loo kolm funktsiooni, vastavalt summa, korrutise ja aritmeetilise keskmise leidmiseks.
  • Aritmeetilise keskmise funktsiooni sisuks ei tohiks olla koopia summa funktsioonist (väldi koodi kopeerimist!). Selle asemel kasuta summa leidmise funktsiooni keskmise leidmise osana.
  • Kõik kolm funktsiooni saavad parameetriteks massiivi ja selle pikkuse ning peavad oma tulemused tagastama. Tulemused väljastatakse main()  funktsioonis.
  • Kuva aritmeetiline keskmine kolme komakohaga
Testimine

Selle ülesande kõige suuremaks komistuskiviks on õige aritmeetilise keskmise leidine.

Lisaülesanne 2: n-arvu sisestus

Pakkumaks kasutajale veidi kasulikumat programmi, peaks kasutaja saama otsustada mitme numbri pealt ta statistikat soovib leida. Pakume kasutajale võimaluse sisestada sisestatavate arvude koguse.

NB! Kuigi suur osa C keele kompilaatoritest toetab muutuva pikkusega massiivide (VLA – variable length array) kasutamist, ei ole see kõigi C standardite kohustusliku osana. St tugi võib kompilaatoris puududa täielikult)

Täiendavalt on VLAde puhul ka teisi probleeme – nt on need sageli aeglasemad kui staatilise suurusega massiivid. VLAd sisaldav kood sisaldab rohkem käske, mis omakorda vajab rohkem protsessori tsükleid (aega) rakenduse jooksutamiseks. Samuti kui ühtegi rangelt nõutud piirangut ei ole, siis on üsna lihtne kogu programm kokku jooksutada, andes ette lihtsalt suurema numbri (nt tahan sisestada 1 000 000 numbrit).

Seetõttu ei ole sul sel korral lubatud kasutada massiive, mille pikkus on määratud teise muutuja kaudu (nt int numbers[numberCount]; , kus numberCount  on täisarvuline muutuja, mis saab oma väärtuse programmi töö ajal). Standardis toetatud universaalne lahendus on kasutada dünaamilist mälu, kuid seda vaatame Programmeerimine 2 aine raames.

Selle ülesande raames peaksid leidma ja määrama maksimaalse võimaliku suuruse, millest kasutaja rohkem numbreid sisestada ei saa. See tähendab, et suure tõenäosusega jääb suur osa massiivi pesadest kasutama. Õnneks on suurused väikesed, seega märkimisväärset probleemi see ei tekita meile.

NB! Enamjaolt on selles aines VLAde kasutamine lubatud. Piirang on seatud ülesandepõhiselt.

Nõuded
  • Luba kasutajal pärast programmi käivitamist otsustada mitme numbriga programm töötab.
  • Piira programmi poolt toetatud numbrite kogust vastavalt loodud massiivi suurusega,
  • Kasutaja poolt sisestuse küsimine peab olema teostatud eraldi funktsioonis, mille pead looma selle ülesande jaoks. Funktsioon tohib alles siis tagastada, kui sisestatud number on sobilik.
    • Kasuta funktsiooni parameetreid piirangute seadistamiseks.
    • Funktsioon mille lood peaks olema korduvkasutatav teistes sarnastes situatsioonides (kuid teiste piirangutega)
  • Numbrite vahemiku võid ise otsustada mõistlikus vahemikus (nt kuni 50 numbrit).
  • Ebasobiva numbrite arvu korral loo veakäitumine.
  • Muutuva pikkusega massiivi (VLA – variable length array) kasutada ei tohi.
  • NB! Vaata üle ka koodimisstiil! Muutuja ei tohi olla kirjutatud samas stiilis nagu makro (tüüpviga).
Testimine

Testi hoolikalt kindlasti järgmist

  • Minimaalne lubatud numbrite arv
  • Maksimaalne lubatud numbrite arv
  • Numbrite arv, mis on erinev algsest

Pärast tundi peaksid

  • Tutvuma kodutöö 1 nõuete ja tutvustavate videotega
  • Teadma mida tähendab tüübiteisendus ning kuidas seda kasutada (type casting)
  • Teadma mis asi on murdarvude esitustäpsus ning mis probleeme sellega esineda võib
  • Teadma mis asi on püsikomaarv (fixed point notation) ja mis on ujukomaarv (floating point notation).
  • Teadma mis asi on matemaatika teek (math.h), kuidas seda kasutada, mis seal sees on ning kuidas lisada kompilaatorile täiendav lipp, et see ka kompileeruks.
  • Teadma mis asi on massiiv
  • Oskama massiivi deklareerida
  • Oskama massiivi algväärtustada
  • Oskama indekseerida igat massiivi liiget
  • Oskama indekseerida massiive kasutades tsükleid
  • Oskama leida ekstreemväärtusi arvujadast

Täiendav materjal