tirsdag 30. oktober 2007

Sesongavslutning

Siste forelesning i kurset blir torsdag 1/11. Tema: arv og polymorfi (resten av kap. 11). Det gir tilsammen 28 forelesninger a 2 timer i semesteret, pluss ukentlige timer (av varierende mengde, riktignok) sammen i laboratoriet.

De resterende uker (ca. 45 dager til eksamen) oppfordres dere til å studere eksamenssettene, løse oppgaver i boken, se på notatene fra kurset og simulere det å løse oppgaver på papir. Neste uke blir det arrangert en simulert eksamen med et av eksamenssettene. Hjelpelærerne vil samle inn papirbesvarelsene og gi dere tilbakemelding i etterkant (uken etter).

ALLE HJELPEMIDLER TILLATES bortsett fra at man ikke kan kontakte andre personer under eksamineringen. Mobiltelefoner skal ikke brukes. Man kan ta med læreboken, kodelistinger og annet man klarer å bære med seg i lokalet.

For at flest mulig skal kunne ta eksamen (11. des.) blir det ikke angitt flere oblig (oblig 9 er den siste). Fristen for innlevering for oblig 1 til oblig 9 er ABSOLUTT: 16/11. De som IKKE har levert da gis IKKE ADGANG TIL EKSAMEN.

Send meg gjerne spørsmål. Jeg svarer til ibe150-listen, slik at det blir rettferdig (alle ser).

mandag 29. oktober 2007

Mandag 29/10: Metoder og frekvenstabell

Vi (8 oppmøtte!) besvarte 2006-eksamen (deloppgave 3 g) med en frekvensteller som spurte oversettelser hvilken bokstav de ville bli sortert etter (første bokstav i det norske ordet). Altså ble ov-klassen utvidet med en metode (nytt, s. 555) som alltid gir stor bokstav:
    Public Function sortBokstav() As Char
        Return _norsk.ToUpper().Substring(0, 1)
    End Function
Klienten (frekvenstelleren, se forøvrig s. 315 i pensum):
    Private Sub Button3_Click(ByVal sender As System.Object, _
                  ByVal e As System.EventArgs) Handles Button3.Click
        lagFrekTabell(o, lst)
    End Sub
    Private Sub lagFrekTabell(ByRef o() As ov, byref l as listbox)
        Dim antall(255) As Integer
        l.Items.Clear()
        Dim i As Integer
        For i = 0 To nl - 1
            Dim pos As Integer = Asc(o(i).sortBokstav())
            antall(pos) += 1
        Next
        For i = 65 To 90   ' a til z (se s. 605)
            l.Items.Add(Chr(i) & " eller " & Chr(i + 32) _
                & ": " & antall(i))
        Next
        i = 198  ' æ
        lst.Items.Add(Chr(i) & " eller " & Chr(i + 32) & ": " & antall(i))
        i = 216  ' ø
        lst.Items.Add(Chr(i) & " eller " & Chr(i + 32) & ": " & antall(i))
        i = 197  ' å
        lst.Items.Add(Chr(i) & " eller " & Chr(i + 32) & ": " & antall(i))
    End Sub
Til sist så vi på exercises 11.1.1 og 11.1.2 (s. 563).

fredag 26. oktober 2007

Oblig 9: Kyr som melker

Gjør oppgave 3 (deloppgaver a, b og c) fra eksamen 2004 (høst). Du anbefales å trene objektorientering (som i kap. 11.1) ved å lage en "class ku", men oppgaven sier ingenting om dette. Du kan eventuelt bruke en "structure ku" (som i kap. 7) hvis du vil trene på det istedet. Husk: "Option Strict On". Du leverer som vanlig i ClassFronter (frist 16/11). Hvis du vil (trene til eksamen): Gjør også resten av deloppgavene (d-f) -- de er ikke vanskelige men tar jo tid.

Fredag 26/10: Konstruktører og ordliste

Eksamen høst 2006 ble studert: 15 likt vektede deloppgaver på 6 timer gir
[kd@harr ~]$ bc -l
bc 1.06 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
1/15
.06666666666666666666
360/15
24.00000000000000000000
altså 6.7 % vekt og 24 minutt tid per deloppgave. Vi så på oppgavene 3 a), b), c) og h) og brukte objektorientering (kap. 11.1) med konstruktør (nytt, s. 560):
[kd@harr ordliste]$ more ov.vb
Public Class ov
  Private _norsk As String
  Private _svensk As String

  Public Sub New(ByRef s1 As String, ByRef s2 As String)
      _norsk = s1                ' "konstruktør"
      _svensk = s2
  End Sub

  Public Property norsk() As String
      Get                        ' "getter"
          Return _norsk
      End Get
      Set(ByVal value As String) ' "setter"
          _norsk = value
      End Set
  End Property

  Public Property svensk() As String
      Get
          Return _svensk         ' "getter"
      End Get
      Set(ByVal value As String)
          _svensk = value        ' "setter"
      End Set
  End Property
End Class
og "hovedklassen" (som skaper brukerens visuelle inntrykk):
[kd@harr ordliste]$ more Form1.vb
Public Class Form1
  'Structure ov   ' vi kunne brukt Structure istedet for objekter
  '   Dim norsk As String
  '    Dim svensk As String
  'End Structure
  Dim o(4) As ov
  Dim nl As Integer = 0   ' Christer foreslo navnet
  Dim filnavn As String = "k:\in-kurs\IBE150\ordliste.txt"

  Private Sub Form1_Load(ByVal sender As System.Object, _
              ByVal e As System.EventArgs) Handles MyBase.Load
      lesfil(filnavn)
  End Sub

  Private Sub lesfil(ByVal n As String)
      Dim linjenr As Integer = 0
      Try
          Dim sr As IO.StreamReader = IO.File.OpenText(n)
          Do While Not sr.EndOfStream()
              nyoversettelse(sr.ReadLine(), sr.ReadLine())
              linjenr += 2
          Loop
      Catch ex As IO.IOException
          MsgBox("feil ved lesing av fil i linje " & linjenr)
      End Try
  End Sub

  Private Sub nyoversettelse(ByVal norsk As String, ByVal svensk As String)
      If nl > o.GetUpperBound(0) Then
          Return   ' full mage (ja, vi kunne utvidet)
      End If
      o(nl) = New ov(norsk, svensk)
      nl += 1
  End Sub

  Private Sub Button1_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button1.Click
      nyoversettelse(InputBox("norsk ord: "), InputBox("svensk ord: "))
  End Sub

  Private Sub lagrefil(ByRef n As String)
      Dim sw As IO.StreamWriter
      Try
          sw = IO.File.CreateText(n)
          For i As Integer = 0 To nl - 1
              sw.WriteLine(o(i).norsk())
              sw.WriteLine(o(i).svensk())
          Next
      Catch ex As IO.IOException
          MsgBox("feil ved lagring")
      Finally
          sw.close()
      End Try
  End Sub

  Private Sub Button2_Click(ByVal sender As System.Object, _
             ByVal e As System.EventArgs) Handles Button2.Click
      lagrefil(filnavn)
  End Sub
End Class
Altså brukes en 1D-tabell av objekt (eller Structure, som nevnt i kommentarene). Man kunne (tredje alternativ) bruke et 2D-array med norsk og svensk i kolonne 0 og 1. Eller (fjerde mulighet), ha 1D-array med norsk og svensk ord i annethvert element.

torsdag 25. oktober 2007

Torsdag 25/10: Klasser og kakevern

Kap. 11.1 om Objektorientering. Vi studerte hvordan en (med Class) lager oppskrift (beskrivelsen), og med Private (default) verner egenskaper. Kakeeksempelet gir alle kaker et startnavn, som kan leses og skrives av klienter, men kun gjennom metoden sittnamn(). Klienten aner ikke at variabelen heter _navn. Oppskriften er
Public Class Kake
    Private _navn As String = "prinsessekake"
    Public Property sittnamn() As String
        Get                                    ' "getter"
            Return _navn
        End Get
        Set(ByVal v As String)                 ' "setter"
            _navn = v
        End Set
    End Property
End Class
Klienten lager 11 kaker som legges i et array, men den 12. kaken får ikke plass i den fulle mage (runtimefeil):
Public Class Form1
    Dim kaker(10) As Kake
    Dim kakenr As Integer = 0
    Private Sub Button1_Click(ByVal sender As System.Object, _
               ByVal e As System.EventArgs) Handles Button1.Click
        Dim k As Kake = New Kake()
        k.ShowDialog()
        k.sittnamn() = InputBox("hva er kakens navn? ")
        kaker(kakenr) = k
        kakenr += 1
        visKaker()
    End Sub

    Sub visKaker()
        For i As Integer = 0 To kakenr - 1
            lst.items.add(i & ": " & kaker(i).sittnamn())
        Next
    End Sub
End Class
Det ble påvist fra salen (Kim) at egenskaper kan angis som
   Public readonly navn as string
og da kan klienten bruke "navn" direkte sålenge det kun er LESING det dreier seg om. Det likeste er likevel at lesing og skriving skjer gjennom "getter" og "setter", slik tillatt med "Public Property".

mandag 22. oktober 2007

Mandag 22/10: Todimensjonalitet og potensregning

Vi gjenopplevde kap. 7.5 om 2D-tabeller, dvelte ved ReDim (r,s) der Preserve er greit hvis det kun er endring av siste dimensjon (antall kolonner). Mønsteret for 2D-traversering ble brukt i gruppearbeidene (s. 384, #1 til 5):
 For i = 0 to a.GetUpperBound(0)
    For j = 0 to a.GetUpperBound(1)
       ' gjør noe med a(i,j)
    Next
  Next
9 av 10 programmeringsmiljø har potensfunksjon. Mangler vi (mot all formodning) funksjonen potens(x,n) lager vi den ITERATIVT (trenger "n" antall multiplikasjoner)
  fun potens (x, n) as integer
    produkt = 1
    for i = 1 to n 
       produkt *= x
    next
    return produkt
  end fun
eller REKURSIVT (hvert kall halverer antall multiplikasjoner):
  fun potens (x, n) as integer
    if n = 1 then
       return x
    end if
    if isPartall (n) then
       r = potens (x, n/2)
       return r*r
    else
       r = potens (x, (n-1) / 2)
       return r * r * x
    end if
  end fun

søndag 21. oktober 2007

oblig 8: Todimensjonalitet

Målet er at du skal trene 2D ved å utvide tabellomformeren:
  • du trenger en egen 2D-tabell som du oppretter globalt med navn X2(0,0)
  • Bruker ser en enkelt godt synlig avkryssingsboks med ledeteksten "2D". Denne er ved oppstart ikke avkrysset.
  • Lag den boolske funksjon is2D( ) som returnerer True hvis 2D-feltet er avkrysset. Denne funksjonen skal kalles ALLE steder hvor du ønsker å vite om vi opererer med 2D -- ingen skal under noen omstendighet sjekke denne knappen selv.
  • Hvis 2D-feltet IKKE er avkrysset er det meningen at brukeren er i 1D-modus, og det er da X( ) som bearbeides. I 2D-modus er det X2( ) som bearbeides.
  • ved endring av størrelse skal (hvis 2D) også antall kolonner oppgis. En "Redim" for 2D kan (etter hva jeg forstår) kun preservere hvis det er den 2de dimensjon som endres (ikke første, les s. 380).
  • lag en sub (prosedyre) visTabell(a(,), l) som kan traversere 2D. Denne skal nå vise verdiene fra begge dimensjoner på samme linje, f.eks. for linje 10 med tabellverdier 23 og 37 blir output slik: "10: 23 37". Prosedyren kaller du visTabell(a(,),l). Her er første parameter annerledes "ByRef a(,) as Integer" enn i den eksisterende prosedyren, men den har samme navn. Når programmet har mer enn en prosedyre/funksjon med samme navn og ulike parametere bruker du en teknikk som kalles overloading (overlastede funksjoner).
  • Når brukeren klikker på knappen for elementEndring, må han oppgi to tall hvis is2D() returnerer true. Hvis is2D() er false oppgir bruker fortsatt bare et tall. Husk å kall visTabell(X2, lstA) når endringen er gjort (hvis 2D)
  • lag overlastede funksjoner for finnSum, finnSnitt, finnHoyeste, finnLaveste som tar 2D-tabeller som argument.Funksjonene har samme navn som variantene for 1D, men med to dimensjoner for tabell-parameteret. Funksjonene kontrollerer alle celler i 2D-tabellen.
  • leting etter verdi skjer linje for linje: kolonne 0, 1, 2 ... i linje 1, ditto i linje 2 ... inntil alle linjer er sjekket (eller verdien eventuelt er funnet). Meldingen til bruker skal angi linje og kolonne der funnet inntraff. Bare "finnesUsortert" skal kunne 2D. Hvis du vil: Tilpass "finnesSortert" og "finnesBinaerLet" slik at de kan 2D.
  • Når brukeren klikker på en av knappene som ikke er tilpasset 2D, skal det gis en melding til brukeren: "kan ikke 2D" dersom 2D er valgt.
  • Hvis du vil: Lag tilpasning av "les fil" og "lagre til fil". Bare de linjene i filen som har tall-verdier leses inn i tabellen. Linjer som ikke har tall utelates.. Fyll i med 0 (null) hvis det ikke er tilstrekkelig antall tall. strFeilmelding skal vise hvilke linjer dette gjelder.
  • Hvis du vil: Lag tilpasning av sjekkStigende, der du sjekker neste celle (i,j+1) mot (i,j). Ved linjens slutt, sjekker du siste i linje i mot starten av linje i+1.
  • Hvis du vil: Lag tilpasning av reversering. En 2D tabell (med Y linjer og X kolonner) revererses rundt tabellens "diagonal", slik at f.eks. a(3,7) og a(7,3) byttes. Til dette lager du en generisk prosedyre bytt2D (a, i, j).

fredag 19. oktober 2007

Fredag 19/10: Rekursjon og kursinnhold

Kursinnholdet for IBE150 (les studiehandboka) ble studert, og "Rekursjon" er ikke gjennomgått, men ikke omtalt i læreboken. Det engelske "recur" betyr "gjentakelse". Et fenomen skjer om igjen. Hittil har gjentakelser blitt skrevet ITERATIVT (Do-Loop, For-Next). Men, den kan skrives REKURSIVT. To viktige moment:
  • programmet skal kalle SEG SELV minst en gang
  • programmet skal bryte ut (med "Return" i VB) når det er ferdig -- dette kalles "base case". Uten dette vil rekursjonen gå for langt, hvert kall spiser minne og til slutt resultere i "Out of Memory" kjøretidsfeil (som jo kan fanges med try-catch).
Prøv gjerne eksemplene under på Deres eget apparat: I. Tabellviser. visTabell(X,l) har dere klokelig kodet iterativt:
 
Sub visTabell (a, l)  ' ITERATIV
 For i As Integer = 0 To a.getupperbound(0)
     l.items.add a(i)
 Next
end sub
Klienten kaller denne opp med visTabell(X,lstA) som i tabellomformeren. Men, prosedyren kan kodes rekursivt (selv om det er lurest å gjøre det iterativt):
Sub visTabell (a, l, Byval pos as integer)  ' REKURSIV
 if pos > a.getupperbound(0) Then
    return     ' ikke gå dypere (ferdig!)
 end if
 l.items.add a(pos)
 visTabell (a, l, pos+1)  ' gå dypere!
End Sub
Ved kjøring av en 4-linjers tabell graves en 4-nivås rekursiv brønn:
visTabell(X, lstA, 0)
   visTabell(a, l, 1)
      visTabell(a, l, 2)
         visTabell(a, 1, 3) -- her stoppes rekursjonen!
Eksempel II. Det "klassiske" eksempel er Fibonaccirekken, som Ole og andre Davincikode-lesere visste var 1, 1, 2, 3, 5, 8, 13 ... regel: Neste i rekken er summen av de to foregående. f(n) = f(n-1) + f(n-2) er en rekursiv definisjon, så vi lager en rekursiv kode:
 Function fib (byval n as integer) as integer  ' REKURSIV
    If n < 3 Then
       Return 1
    End If
    Return fib(n-1) + fib(n-2)
 End Function
Denne kan kalles med f.eks. msgbox ("fib 12 er " & fib(12)). Med fib(41) ble kjøretiden ikke bra. Problemet: Samme fibtall (f.ex. f(7)) regnes ut uhorvelig mange ganger. Den rekursive brønn for fib(5)
  fib(5) -- 3 + 2 = retur 2
     fib(4) -- 2+1 = retur 3
        fib(3) -- 1+1 = retur 2
           fib(2) -- retur 1
           fib(1) -- retur 1
        fib(2) -- retur 1
     fib(3) ... (om igjen!!) -- 1+1 = retur 2
        fib(2) -- retur 1
        fib(1) -- retur 1
Det er (også her) lurere å skrive iterativt og bygge en tabell f( ) fra grunnen av (hvert tall regnes da ut bare EN gang):
function fib (byval n as integer) as integer  ' ITERATIV
 dim f(n) as integer
 f(1) = 1
 f(2) = 1
 for i as integer = 3 to n
    f(i) = f(i-1) + f(i-2)  
 next
 return f(n)
end function

torsdag 18. oktober 2007

Torsdag 18/10: Split, join og avvikere

Tema var kap. 8.2 (Split og join) samt stuntprogrammering (av meg) av tabellomformer som leser alle 15000 av 15010 linjer og rapporterer 10 differensierte avvik med automatisk tabellutvidelse idet indeksen går utenfor, uten å glemme tallet som ikke ble lagt inn da kjørefeilen oppstod. To varianter av finnHoyeste(a):
max = a(0)              ' sa olav
max = integer.minvalue  ' sa jeg 
for i = 0 to a.upper                   
  if a(i) > max
    max = a(i)
return max

for i = 0 to a.upper    ' type b:  endrer originalen (hvis byval)
  if a(i) > a(i+1)      ' denne ble brukt i allefall av to studenter (oblig 6)
    a(i+1) = a(i)
return a(a.upper)

mandag 15. oktober 2007

Mandag 15/10: Fil og unntak

Foreleste kap 8.1 (og kap 3.5) om lesing OpenText() med Readline(), skriving med AppendText () eller CreateText() og Writeline), avslutningsvis (og så raskt som mulig) en Close() -- slik at vi ikke oppholder andre lesere (eller skrivere). I grupper besvarte dere Exercises 8.1, nr. 1-4. Etter pausen og Opdals studentundersøkelse gjennomgikk vi strukturert håndtering av avvik (unntak, exception), altså det språklige "try-catch-finally". Til sist gruppearbeidet dere veldig flinke svar til nr. 5-8.

oblig 7

Utvid tabellomformer slik at den leser data fra fil:
  • Bruker ser knapp for "les fil" (btnLesFil) som leser tall fra ei fil (bruker oppgir filnavnet med OpenFileDialog, s. 466).
  • Det første heltallet på linje N i fila legges i N'te element i tabell X. PRESISERING (kl. 13.15):
    • Dette forutsetter jo at alle linjene har legale heltall. Men, noen av linjene har jo ikke dette, og regelen blir da: Neste legale heltall legges i neste ledige element.
    • X skal jo her ha helt nytt innhold. Sett den derfor initielt slik at den har plass til intTabellBlokkstr (et heltall med verdien 100) element. Hvis tabellen (X) blir full kaller du subrutinen nyStorrelse() som du laget i oblig 5, slik at X hver gang utvides med intTabellBlokkstr. Idet du f.eks. legger inn det 101'ste element utvides tabellen til 200. Slik vokser X i etapper fra 100, til 200, 300 o.s.v. Hvis det er 549 virkelige heltall i filen vil X til slutt ha plass til 600 element. Hvis filen bare har 3 virkelige heltall forblir X med plass til 100 element. Filen 15000tall.txt brukes til testing.
  • Du skal bruke tall = Cint (eller din egenutviklede tall = hentHeltall(s)) der s er sist innleste streng fra fila, og lage differensiert behandling av unntak for overflyt (for store tall) og feil typekasting (ex. tom streng).
  • Idet du fanger en feil bygger du (med &-operator) en streng "strFeilmelding" (initielt tom streng). Etter at filen er lest i sin helhet har du en strFeilmelding som f.eks. "Linje 2: Overflyt, linje 17: Ikke heltall, linje 355: ...".
  • Programmet skal IKKE abortere, og ALLTID rapportere en melding (etter at filen er lest) ved å kalle visFeilmelding(strFeilmelding), en prosedyre du kan kalle fra flere steder. Til sist kalles visTabell(a,l) med X og lstA som argument. Du skal fange alle IO-relaterte feil (som beskrives i kap. 8.1) og bygge ut strFeilmelding med MENINGSFULLT innhold.
  • visFeilmelding(s) skal vise strengen s i en msgbox og (i tillegg, i samme msgbox) gi en beskjed om at "Du kan ringe tlf. xxx xxx eller sende ePost til tabellsjef@firmaet.mitt hvis du trenger hjelp". Telefonnumrene og ePost hentes ut av datastrukturen (s. 343) kontaktProgram. Denne er av typen Kontaktinfo (en "Structure Kontaktinfo") som igjen har strengene strNavn, strTelefon og strEPost.
Du kan (kun ved lesing) bruke filene tall.txt og 15000tall.txt som ligger på kursinfo: k:\in-kurs\IBE150. Bruker skal kunne lagre tabellen til fil.
  • Bruker ser knapp "lagre til fil" (btnLagreFil) som lagrer tabell X til en fil, slik at det Nte element i X blir Nte linje i filen.
  • La brukeren oppgi filen med OpenFileDialog (som over).
  • Hvis du vil: Hvis brukeren allerede har valgt "les fil" er det vanligvis greit at det filnavnet som da ble brukt, blir husket globalt (strFilnavn) og foreslått (slik at brukeren slipper all navigeringen)
  • Programmet skal kun reagere på IOException (samlekategori) og kalle opp visFeilmelding ("Feil oppstod ved lagring").

lørdag 6. oktober 2007

Oppgaver i kap. 7

Jeg har forelest kap. 7 om tabeller. Jeg mener dere til repetisjon (og, mens det er forelesningsfri) bør gjøre "Practice problems" og "Exercises" til hvert delkap. i 7. Noen oppgaver gjorde vi i gruppearbeidet, men en god del gjenstår. Oppgaver som kalles " Så finn deres favorittpartner og start arbeidet -- er mitt råd. Jeg kategoriserer dette som LURT!

fredag 5. oktober 2007

Fredag 5/10: Prøve og flere dimensjoner

Jeg oppsummerte oblig 5 og 6. Så hadde vi kontrollprøve der dere besvarte
  1. Lag Sum(a) som finner sum i tabell a
  2. Lag Snitt(a) som (ved gjenbruk av sum) finner snittet av tabell a
  3. Lag Max(a) som finner høyeste verdi i tabell a
Til disse tre har jeg gitt kommentar til 4 av svarene jeg samlet inn:
  1. Husk at sumvariabel må (med sikkerhet) starte på 0 (null)!
  2. Husk at sum(a) / a.getUpperBound(0) blir for høyt!
  3. Husk at HittilHøyeste må initielt være tilstrekkelig lav (f.eks. Integer.MINVALUE), slik at den med sikkerhet ikke overstiger høyeste verdi i tabellen a.
Flere dimensjoner (kap. 7.5): Vi så med lupe på kommentar 1 og 2 (s. 383). En 3D med temperaturer var a(31,24,11) med plass til 32 dager, 25 timer og 12 måneder. Hvis vi også skal huske hundre år tilbake i tid opprettes en 4D med a(31,24,11,99). Og, kommentar #2 forteller at vi ikke kan redimensjonere til flere dimensjoner -- kun flytte yttergrensene i de dimensjoner vi har! Redim av en 2D tabell til det dobbelte antall kolonner:
 
  Redim a ( _
    a.getUpperBound(0) , _
   (2*a.getUpperBound(1)) + 1 )

tirsdag 2. oktober 2007

Oblig 6: Utvidet tabellomformer

Hensikten er ytterligere styrking av kunnskap om tabeller, løkker og funksjoner. Du skal utvide tabellomformeren i oblig 5. Frist: 12/10.
  • Bruker ser en knapp for "Finn sum" (btnSum) som kaller funksjonen Sum(r) med X som argument. Resultatet fra sum() skrives i msgbox.
  • Bruker ser en knapp for "Finn snitt" (btnSnitt) som gjenbruker funksjonen Sum (se over) til utregning. Til sist skrives gjennomsnittet i msgbox.
  • Bruker ser en knapp for "Finn høyeste" (btnHoyest) som kaller funksjonen finnHoyeste(r) med X som argument og skriver resultatet i msgbox.
  • Bruker ser en knapp for "Finn Laveste" (btnLavest) som kaller funksjonen finnLaveste(u) med X som argument og skriver resultatet i msgbox.
  • Bruker ser en gruppeboks (grpLeting). Inni denne er en knapp for "Leting" (btnLeting), samt tre bokser for leteMetode, hvorav en (og bare en) skal være avkrysset. Hvis btnLeting trykkes skal du med inputboks (og hentHeltall) be brukeren oppgi intTall som det skal letes etter. Deretter iverksettes leting med valgt metode (sjekk radUsortert, radSortert eller radBinaerLet, s. 474). Ved oppstart (Form.Load) SKAL den MEST effektive letemetoden avkrysses! Eventprosedyren for grpLeting skal kalle en av tre boolske funksjoner og vise resultatet ved å farge bakgrunnen i lstA rosa (hvis ingenting ble funnet) -- det er jo oktober -- eller hvit (hvis True)! Du skriver derfor:
    • finnesUsortert(p,v) med X og intTall som argument -- denne antar at tabellen er usortert og må sjekke alle for å eventuelt avgjøre at tallet ikke finnes!
    • finnesSortert(p,v) med X og intTall som argument -- denne antar at tabellen er sortert stigende, begynner i posisjon 0 (null), og kan avbryte letingen hvis den har lett for langt!
    • finnesBinaerLet(p,v) med X og intTall som argument -- denne antar stigende sortert og leter binært (fjerner halvparten av leteområdet hver gang).
    Alle tre funksjonene skal telle antall sammenligninger (intAntSammenlgn). Hver funksjon SKAL selv kalle prosedyren visLeteresultat(hvem, tabell, tall, posisjon, intAntSammenlgn) som f.eks. (med argumentene "finnesSortert", x, 37, 11020 og 421) sier "finnesSortert: Fant 37 i posisjon 11020 av 14000. 421 sammenligninger!". Hvis argumentet "posisjon" oppgis til -1 mener letefunksjonen at den IKKE fant noe. Det er visLeteresultat() som SELV finner ut hvor stor tabellen var, f.eks. at oppgitt tabell x() hadde 14000 element!
Hvis du vil:
  • Bruker ser en knapp for "krymping" (btnKrymping) som ber brukeren oppgi heltallet intFaktor (inputboks og hentHeltall). Tallet sier hvor mye tabellen X skal krympes: Hvis 2 beholdes annethvert element, hvis 3 beholdes tredjehvert ... løkken starter med at element 0 (null) beholdes. De du beholder kan legges i en lokal hjelpetabell Y som er akkurat stor nok. Hvert element som beholdes kopieres da dit: Y(..) = X(..). Til sist fjerner du X og lar X settes til Y (s. 316).
  • Legg til funksjoner som var valgfrie i oblig 5 (randomiser, lineariser, sorter).

mandag 1. oktober 2007

Mandag 1/10: Lur leting og regning med tabeller

Vi leter etter "Truls" i en tabell a() med 1 million (N) element
  • hvis a() er usortert må vi lete gjennom alle N element før vi erklærer "ikke funnet"
  • hvis a() er sortert stigende kan vi avbryte etter posisjon k hvis a(k) > "Truls"
  • hvis a() er sortert kan vi gjøre et binærsøk (kap. 7.4). Ved å sjekke a(N/2), midtveis, kan en erklære halvparten av a() som uinteressant. Hver sjekk halverer søkeområdet. Hvis "Truls" ikke er i tabellen har vi gjort log2 (1,000,000) som er omtrent 20 sjekker (istedetfor å sjekke alle en million).
På tavla stod en tabell R() med { 0, -1, 6, 4 } som innhold. I gruppearbeid laget alle 9 :-( av dere, funksjoner for Sum(R), snitt(R) og median(R).
 Function sum (ByValRef a() as Integer) As Integer
   ' laget av Orjan og Johan
   Dim s as Integer = 0
   For i as Integer = 0 to a.getUpperBound(0)
      s += a(i)
   Next
   Return s
 End Function

 Function snitt (ByValRef x() as Integer) as Double
   ' laget av Orjan og Johan
   Return sum(x) / (x.getUpperBound(0)+1)
 End Function

 Function Median (ByValRef m() as Integer) as Double
   ' klassen viste meg hva median er (s. 376)
   Dim n as Integer = m.getUpperBound(0) + 1
   If isPartall(n)
      Return ... (ikke ferdig)
   Else
      Return ...
   End If
 End Function

 Function isPartall (DimByVal y as Integer) as Boolean
    If y Mod 2 = 0 ...
 End Function
Håpet om å lage funksjonene laveste(R) og høyeste(R) utsettes. Disse funksjonene vil nok kunne legges til tabellomformeren i oblig 5.