Mikroandmebaasi ülesande soovitusi ja nõuandeid: erinevus redaktsioonide vahel

Allikas: Lambda
Mine navigeerimisribale Mine otsikasti
Resümee puudub
27. rida: 27. rida:
* where lause iga üksik komponent tulp1=vaartus1, kus eraldajaks = ja komponente alati kaks.
* where lause iga üksik komponent tulp1=vaartus1, kus eraldajaks = ja komponente alati kaks.


Kuidas seda paremini teha? Esiteks, iga sellise lammutamise tulemuseks tasub anda
Kuidas seda paremini teha?  
 
Esiteks, iga sellise lammutamise tulemuseks tasub anda
stringimassiivi, kus elementideks on järjest vajalikud stringid. Hea on, kui see stringimassiiv teha kohe õige pikkusega, siis saab mh lihtsamalt kontrollida, kui palju elemente temas on (massiiv.length annab massiivi pikkuse).
stringimassiivi, kus elementideks on järjest vajalikud stringid. Hea on, kui see stringimassiiv teha kohe õige pikkusega, siis saab mh lihtsamalt kontrollida, kui palju elemente temas on (massiiv.length annab massiivi pikkuse).


Stringi lammutamiseks on palju meetodeid, kuid kõige lihtsam on uurida näiteprogrammi [splitproov.java] ja kasutada seal olevaid ideid. NB! Selleks, et selle programmi lõike kasutada, on vaja, et sa temast aru saaksid.
Teiseks, mõistlik on kirjutada funktsioon, mis võtab ette lammutatava stringijupi,
eraldaja-stringi (koma või and vÕi =) ja annab tagasi stringimassiivi.


Stringi lammutamiseks on palju meetodeid, kuid kõige lihtsam on uurida näiteprogrammi [splitproov.java] ja kasutada seal olevaid ideid. NB! Selleks, et selle programmi lõike kasutada, on vaja, et sa temast aru saaksid. Vaata kindlasti ka massiivide kasutamise näiteprogrammi [massiivproov.java]


=== where lause tükkideks lõhkumine ===
=== where lause tükkideks lõhkumine ===

Redaktsioon: 24. september 2005, kell 02:17

Kuidas pihta hakata ja mis järjekorras programmeerida?

Põhimõte:

Hakka kirjutama valmis üksikuid juppe, alates lihtsamatest. Kui üks on valmis, testi ta läbi ja mine siis järgmise kallale. Alles lõpuks pane kõik main-i sees kenasti kokku.

Soovitaksin teha tükid valmis näiteks sellises järjekorras:

  • Funktsioon, mis loeb select lausest välja failinimed ja tingimused ja paneb need vastavatesse massiividesse.
  • Funktsioon, mis saab ette failinime, seepeale loeb sisse vastava csv faili ja tagastab kahemõõtmelise stringimassiivi, mille sees selle csv faili väljad (stringid) ridade kaupa.
  • Funktsioon, mis genereerib järjest kõik kombinatsioonid kõigi sisseloetud massiivide ridadest (täielik ristkorrutis).
  • Funktsioon, mis võtab ette ühe taolise ristkorrutise rea (stringimassiivi) ja kontrollib, kas see rida vastab where tingimustele select lauses (kasutades muidugi varem-ehitatud massiivi, kus where tingimused sees).
  • Pane tükid järjest kokku, kutsudes neid main funktsiooni sees järjest välja (kõigepealt select lause analüüs, siis tsükkel üle failinimede, kutsudes iga kord välja faili sisselugemise funktsiooni, siis ristkorrutise ehitamine, mis omakorda kutsub iga genereeritud rea jaoks välja where tingimuste kontrolli-funktsiooni.

Soovitusi funktsioonide kirjutamisel

Stringi lõhkumine eraldaja järgi

Sinu programm peab päris mitmes kohas lammutama eraldajaga stringi tükkideks:

  • select lauses from (tabelite/failide) osa, eraldajaks komad: fail1, fail2, ...,failn
  • select lauses where tingimused, eraldajaks and: tulp1=vaartus1 and .... and tulpm=vaartusm
  • kettalt loetud csv faili rida, eraldajaks jällegi komad
  • where lause iga üksik komponent tulp1=vaartus1, kus eraldajaks = ja komponente alati kaks.

Kuidas seda paremini teha?

Esiteks, iga sellise lammutamise tulemuseks tasub anda stringimassiivi, kus elementideks on järjest vajalikud stringid. Hea on, kui see stringimassiiv teha kohe õige pikkusega, siis saab mh lihtsamalt kontrollida, kui palju elemente temas on (massiiv.length annab massiivi pikkuse).

Teiseks, mõistlik on kirjutada funktsioon, mis võtab ette lammutatava stringijupi, eraldaja-stringi (koma või and vÕi =) ja annab tagasi stringimassiivi.

Stringi lammutamiseks on palju meetodeid, kuid kõige lihtsam on uurida näiteprogrammi [splitproov.java] ja kasutada seal olevaid ideid. NB! Selleks, et selle programmi lõike kasutada, on vaja, et sa temast aru saaksid. Vaata kindlasti ka massiivide kasutamise näiteprogrammi [massiivproov.java]

where lause tükkideks lõhkumine

Kah kasulikke soovitusi

Tulpade numbrilised indeksid vs tulpade nimed

Kasuta oma funktsioonides tulpade indekseid (numbreid), mitte aga nende nimesid! Argumendiks saadud nime järgi leia esimese ülesandena kohe tulba number (tee tsükkel üle päiserea, kuni leiad antud nime), ja pärast kasuta siis ainult seda numbrit.

Stringide võrdlemine

NB! Kui x ja y on stringid, siis võrdlemine

 x==y

ei anna oodatud tulemust! See võrdlus ainult kontrollib, kas x ja y on võrdsed pointerid, st viitavad samale stringile mälus. Aga, kui teeme nii:

 String x="ab";
 String y="ab";
 if (x==y) ...

siis x ja y on erinevad pointerid (kuigi stringide sisud on samad!) ja neid ei peeta võrdseks.

Selleks, et kontrollida, kas stringide sisud on samad, on vaja kasutada sellist spetsiaalset stringivõrdlust:

 x.equals(y)

(selle funktsiooni ja muud head stringifunktsioonid leiab nii Ecki õpikust kui ametliku manuaali lingilt http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html)

Võrdlemaks, kas string x on suurem kui string y (vajalik sorteerimisel), kasuta järgmist funktsiooni:

 x.compareTo(y)

Lisainfot (mitte väga olulist) leiad eelnevalt viidatud linkidest.

Mida compareTo välja annab? int-i. Mida see int näitab? Katseta ise: võrdle paari stringi (pane katse main funktsiooni) ja trüki tulemus-int välja.


Kuidas teha õige suurusega massiiv, kui näiteks failist loed?

Probleem selles, et meil on vaja panna failist loetud stringid massiivi, aga me ei tea ette, kui suur on fail. Seega, kui suur massiiv tuleks teha?

Siin on, nagu alati mitu lahendust.

Hästi lihtne ja ebaefektiivne lahendus on kõigepealt lugeda fail sisse, aga mitte massiivi panna: selle asemel lugeda kokku ridade arv (ja tulpade arv ka).

Siis teeme õige suurusega massiivi ja loeme seejärel failist uuesti kõik read, seekord pannes nad massiivi sisse.

Elegantsem lahendus on vältida mitmekordset lugemist. Aga: kui sa endas väga kindel ei ole, soovitan algul realiseerida lihtsama lahenduse, mida äsja kirjeldasin.

Elegantsema lahenduse saab kirjutada näiteks nii:

Esiteks loeme sisse esimese rea ja vaatame, mitu tulpa seal on. Siis teame kohe massiivi teist (tulpade arvu) dimensiooni. Järgmistes ridades peab ju olema sama palju tulpasid.

Nüüd ei tea me ikkagi, mitu rida massiivis on.

Järgmisena teeme esialgse, ajutise massiivi näiteks suurusega 100 rida (ja õige arv tulpasid). Hakkame sinna lugema. Kui fail mahtus ära, teeme uue massiivi, seekord õige (lühema) pikkusega, ja kopeerime esialgse massiivi vajalikud read sinna massiivi. Vana massiiv visatakse mõne aja pärast prahikoristaja poolt automaatselt ära.

Kui fail ei mahtunud esialgsesse massiivi, teeme uue ajutise massiivi, seekord näiteks 2 korda suurema kui eelmine. Kopeerime vanast ajutisest kõik uude ajutisse ja jätkame failist uude massiivi lugemist. Võib juhtuda, et nüüd mahub ära. Siis lõpuks teeme õige pikkusega (lühema) massiivi.

Kui ikka ei mahtunud, kordame protseduuri: teeme jälle uue, viimasest masiivist jällegi kaks korda suurema ajutise masssiivi. Jne jne.

NB! Selliselt ajutisi massiive tehes pane tähele, et kuna tulpade arv on neis alati õige, ei ole tegelikult vaja kopeerida vanast massiivist uude üksikute stringide kaupa (st topelttsükliga). Kahemõõtmeline massiiv on ju massiiv mitmest ühemõõtmelisest! Kopeerimise käigus saame kopeerida korraga terve rea (käsitledes massiive kui ühemõõtmelisi) ja see on palju kiirem meetod. Siin on veel võimalik teha mitu täiendavat optimeeringut, aga liiale ei ole optimeerimis-pingutustega ka mõtet minna.