Delphi

Stian Søiland, IT 112, øvingsgruppe 15 (stud.ass. Helle Haugenes)

Delphi - Øving 2 - Oppgave 1

unit telefonkatalog;
  // Abstrakt datatype-enhet for telefonkatalog
  // ADTen oppretter og vedlikeholder en telefonkatalog.
  // Vi antar på forhånd at det alltid vil finnes bare ett telefonnummer
  // til hvert navn, og kun en oppf¢ring av hvert navn.
  // Vi antar også, noe naivt, at ingen har samme telefonnummer.

  // offentlig del av ADT
  interface
    // Antall siffer i telefonnummer. Antas alltid brukt, dvs. ingen
    // telefonnummer har verken FÆRRE eller FLERE siffer enn dette.
    const sifferitelefonnummer = 8;

    type

      // Typedeklarasjon for navn. Indre formattering med hensyn til fornavn,
      // etternavn, etc. defineres ikke av ADT.
      navntype = string;

      // Typedeklarasjon for telefonnummer. Konstanten sifferitelefonnummer er
      // gitt tidligere i enheten.
      nummertype = string[sifferitelefonnummer];

      // Typedeklarasjoner for lenket resultatliste med navn og nummer
      oppforingpeker = ^oppforing;
      oppforing = record
           navn : navntype;
         nummer : nummertype;
          neste : oppforingpeker;
             end;

      // Prosedyren initier oppretter telefonkatalogen, resultat er sann ved
      // suksess.
      procedure initier(var resultat:boolean);

      // Prosedyren legginn legger til oppf¢ring med navn og nummer til
      // telefonkatalogen og resultat er sann hvis prosedyren var vellykket.
      // Dersom en oppf¢ring med 'navn' finnes fra f¢r vil prosedyren
      // feile og resultat blir negativt.
      procedure legginn(navn:navntype; nummer:nummertype;
                        var resultat:boolean);

      // Prosedyren finnnummer returnerer telefonnummeret til navn. Navnet
      // må være fullstendig. Resultat er sann dersom navnet ble funnet,
      // i alle andre tilfeller er den usann.
      procedure finnnummer(navn:navntype; var nummer:nummertype;
                     var resultat:boolean);

      // Prosedyren finntelefonnummer returnerer det
      // navnet som har telefonnummer likt nummer. Nummeret må
      // være fullstendig. Resultat er sann dersom nummeret ble funnet,
      // i alle andre tilfeller er den usann.
      procedure finnnavn(nummer:nummertype;var navn:navntype;
                         var resultat:boolean);

      // Prosedyren slettnavn sletter oppf¢ringen med det gitte navnet.
      // Resultat er sann hvis prosedyren usann og navnet ble funnet,
      // er navnet ikke oppf¢rt, er resultat usann.
      procedure slettnavn(navn:navntype; var resultat:boolean);

      // Prosedyren listalle returnerer en peker til en lenket liste,
      // alfabetisk sortert etter navn, over alle oppf¢ringene i
      // telefonkatalogen. Resultat er sann dersom listingen er vellykket.
      procedure listalle(var resultatliste:oppforingpeker;
                         var resultat:boolean);

  // Privat del av ADT
  implementation

    // Global variabel hode for å holde fast i den lenkede listen som utgj¢r
    // telefonkatalogen. Bruker samme datatype som listalles resultatliste.
    // Den lenkede listen er usortert.
    var hode:oppforingpeker;

    // Oppretter telefonkatalogen. Eventuelle eksisterende
    // noder i den lenkede listen blir slettet.
    // Hode-parameteren blir nullstilt i initialization-delen av
    // enheten slik at den aldri vil peke til en ikkeeksisterende
    // dynamisk variabel.
    procedure initier(var resultat:boolean);
      var temp:oppforingpeker;
      begin
        if hode <> nil then
         begin
           temp := hode;
           hode := hode^.neste;
           dispose(temp);
           // rekursivt kall
           initier(resultat);
         end
        else
         // degenerert tilfelle
         begin
           resultat := true;
         end;
      end; // slutt initier

    // Funksjonen posisjonnavn returnerer en peker til noden i den
    // lenkede listen som er F¥R navn. Dersom navn ikke er oppf¢rt
    // vil pekeren være NIL.
    function posisjonnavn(posisjon:oppforingpeker;
                          navn:navntype):oppforingpeker;
      begin
        if (posisjon = nil) or (posisjon^.navn <> navn) then
         begin
           // rekursivt kall
           posisjonnavn := posisjonnavn(posisjon^.neste,navn);
         end
        else
         begin
           // degenrert tilfelle
           posisjonnavn := posisjon;
         end;
       end; // slutt posisjonnavn

    // Funksjonen posisjonnummer returnerer en peker til noden i den
    // lenkede listen som er F¥R nummer. Dersom nummer ikke er oppf¢rt
    // vil pekeren være NIL.
    function posisjonnummer(posisjon:oppforingpeker;
                          nummer:nummertype):oppforingpeker;
      begin
        if (posisjon = nil) or (posisjon^.nummer <> nummer) then
         begin
           // rekursivt kall
           posisjonnummer := posisjonnummer(posisjon^.neste,nummer);
         end
        else
         begin
           // degenrert tilfelle
           posisjonnummer := posisjon;
         end;
       end; // slutt posisjonnavn

    procedure legginn(navn:navntype; nummer:nummertype;
                      var resultat:boolean);
      // Prosedyre for å lage ny node
      procedure nynode;
        var temp:oppforingpeker;
        // Lager ny node i begynnelsen av den lenkede listen
        begin
          new(temp);
          temp^.neste := hode;
          hode := temp;
        end; // slutt nynode

      begin
        // Sjekker om navn eller nummer finnes fra f¢r i listen
        if (posisjonnavn(hode,navn) <> nil) or
           (posisjonnummer(hode,nummer) <> nil) then
          begin
            nynode;
            hode^.navn := navn;
            hode^.nummer := nummer;
            resultat := true;
          end
         else
          begin
            // Navnet eller nummeret fantes fra f¢r, kunne ikke legge til
            resultat := false;
          end;
      end; // slutt legginn

    procedure slettnavn(navn:navntype; var resultat:boolean);
      var temp1,temp2:oppforingpeker;
      begin
        temp1 := posisjonnavn(hode,navn);
        if temp1 <> nil then
          begin
            temp2 := temp1^.neste;
            // Linker forbi noden som skal slettes
            temp1^.neste := temp2^.neste;
            dispose(temp2);
            resultat := true;
          end
         else
          begin
            // Navnet fantes ikke, kunne ikke slette
            resultat := false;
          end;
      end; // slutt slettnavn

    procedure finnnummer(navn:navntype; var nummer:nummertype;
             var resultat:boolean);
      var temp:oppforingpeker;
      begin
        temp := posisjonnavn(hode,navn);
        if temp <> nil then
          begin
            // Returnerer telefonnummeret
            nummer := temp^.neste^.nummer;
            resultat := true;
          end
         else
          begin
            // Navnet fantes ikke, nummer kan ikke returneres
            resultat := false;
          end;
      end; // slutt finnnummer

    procedure finnnavn(nummer:nummertype; var navn:navntype;
             var resultat:boolean);
      var temp:oppforingpeker;
      begin
        temp := posisjonnummer(hode,navn);
        if temp <> nil then
          begin
            // Returnerer navnet
            navn := temp^.neste^.navn;
            resultat := true;
          end
         else
          begin
            // Nummeret fantes ikke, navnet kan ikke returneres
            resultat := false;
          end;
      end; // slutt finnnavn

    procedure listalle(var resultatliste:oppforingpeker;
                 var resultat:boolean);

      function posisjon(navn:navntype; listehode:oppforingpeker):oppforingpeker;
        begin
          if listehode <> nil and listehode^.navn > navn then
            begin
              // rekursivt kall
              posisjon := posisjon(navn,listehode^.neste);
            end;
           else
            begin
            // Degenerert tilfelle
            posisjon := listehode;
            end;
        end;

      procedure settinn(navn:navntype; nummer:nummertype;
                        var listehode:oppforingpeker);
        var temp:oppforingpeker;
        begin
          new(temp);
          temp^.navn := navn;
          temp^.nummer := nummer;
          temp^.neste := listehode;
          listehode := temp;
        end;

      function sorter(gammel,ny:oppforingpeker):oppforingpeker;
        var temp:oppforingpeker;
        begin
          if gammel <> nil then
            begin
              settinn(gammel^.navn,gammel^.nummer,posisjon(gammel^.navn,ny));
              sorter := sorter(gammel^.neste,ny);
            end
           else
            begin
              sorter := gammel;
            end;
        end; // slutt sorter

      begin
       resultatliste := sorter(hode,nil);
      end; // slutt listalle



  initialization
    // Nullstiller global parameter hode
    hode := nil;
end.

 


© Stian Søiland 1999

Valid HTML 4.0!