Løsningsforslag - oppgaver i Avsnitt 1.1.7


Oppgave 1

Nedenfor står klassen Program med metoden maks fra Programkode 1.1.2 og makstest. Når klassens main-metode kjøres, skjer ingenting. Med andre ord ingen feilmeldinger.

public class Program
{
  public static int maks(int[] a)  // a er en heltallstabell
  {
    if (a.length < 1)
      throw new java.util.NoSuchElementException("a er tom");

    int m = 0;  // indeks til største verdi

    for (int i = 1; i < a.length; i++) // obs: starter med i = 1
    {
      if (a[i] > a[m]) m = i;  // indeksen oppdateres
    }

    return m;  // returnerer indeksen/posisjonen til største verdi

  } // maks

  public static void makstest()
  {
    int[] a = {8,3,5,7,9,6,10,2,1,4};  // 10 er i posisjon 6

    if (maks(a) != 6)  // kaller maks-metoden
      System.out.println("Feil posisjon!");

    a = new int[0];  // en tom tabell
    boolean unntak = false;

    try
    {
      maks(a);  // kaller maks-metoden
    }
    catch (Exception e)
    {
      unntak = true;
      if (!(e instanceof java.util.NoSuchElementException))
        System.out.println("Kaster feil unntak for en tom tabell!");
    }

    if (!unntak)
      System.out.println("Det skal kastes unntak for en tom tabell!");
  }

  public static void main(String[] args)
  {
    makstest();
  }

} // class Program

Oppgave 2

En utvidet versjon av metoden makstest:

  public static void makstest()
  {
    int[] a = { 8, 3, 5, 7, 9, 6, 10, 2, 1, 4 };  // 10 er i posisjon 6

    int antallfeil = 0;

    if (maks(a) != 6) // kaller maks-metoden
    {
      System.out.println("Test 1 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { 10, 9, 8, 7, 6 };

    if (maks(a) != 0) // kaller maks-metoden
    {
      System.out.println("Test 2 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { 1, 2, 3, 4, 5 };

    if (maks(a) != 4) // kaller maks-metoden
    {
      System.out.println("Test 3 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { 2, 3, 3, 5, 3, 5, 4 };

    if (maks(a) != 3) // kaller maks-metoden
    {
      System.out.println("Test 4 - feil posisjon!");
      antallfeil++;
    }

    a = new int[]{ 2 };

    if (maks(a) != 0) // kaller maks-metoden
    {
      System.out.println("Test 5 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { 1, 2 };

    if (maks(a) != 1) // kaller maks-metoden
    {
      System.out.println("Test 6 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { 2, 1 };

    if (maks(a) != 0) // kaller maks-metoden
    {
      System.out.println("Test 7 - feil posisjon!");
      antallfeil++;
    }

    a = new int[] { -5, -5 };

    if (maks(a) != 0) // kaller maks-metoden
    {
      System.out.println("Test 8 - feil posisjon!");
      antallfeil++;
    }

    a = new int[0];  // en tom tabell
    boolean unntak = false;

    try
    {
      maks(a);  // kaller maks-metoden
    } catch (Exception e)
    {
      unntak = true;
      if (!(e instanceof java.util.NoSuchElementException))
      {
        System.out.println("Kaster feil unntak for en tom tabell!");
        antallfeil++;
      }
    }

    if (!unntak)
    {
      System.out.println("Det skal kastes unntak for en tom tabell!");
      antallfeil++;
    }

    a = null;
    unntak = false;
    try
    {
      maks(a);  // kaller maks-metoden
    } catch (Exception e)
    {
      unntak = true;
      if (!(e instanceof NullPointerException))
      {
        System.out.println("Kaster feil unntak for en null-tabell!");
        antallfeil++;
      }
    }

    if (!unntak)
    {
      System.out.println("Det skal kastes unntak for en null-tabell!");
      antallfeil++;
    }

    System.out.println("Antall feil: " + antallfeil);
  }

Oppgave 3

Programkode 1.1.4

  1. I setningen int maksverdi = a[0]; vil det under kjøring av programmet bli sjekket om a er null eller ikke. Hvis a er null blir det kastet en NullPointerException, og det er slik det skal være.
  2. Hvis a er tom (a.length = 0), vil a[0] gi en ArrayIndexOutOfBoundsException. Hvis vi ønsker at det skal kastes en NoSuchElementException for en tom tabell, må metoden inneholde en test på om tabellen er tom. Da blir metoden slik:
  public static int maks(int[] a)   // versjon 2 av maks-metoden
  {
    if (a.length < 1)
    {
      throw new java.util.NoSuchElementException("a er tom");
    }

    int m = 0;               // indeks til største verdi
    int maksverdi = a[0];    // største verdi

    for (int i = 1; i < a.length; i++)
    {
      if (a[i] > maksverdi)
      {
        maksverdi = a[i];     // største verdi oppdateres
        m = i;                // indeks til største verdi oppdaters
      }
    }
    return m;   // returnerer indeks/posisjonen til største verdi

  } // maks

Programkode 1.1.5

  1. Setningen int sist = a.length - 1; vil gi en NullPointerException hvis a er null.
  2. Setningen int maksverdi = a[0]; vil gi en en ArrayIndexOutOfBoundsException hvis a er tom. Hvis det skal kastes en NoSuchElementException for en tom tabell, må metoden inneholde en test på om tabellen er tom. I flg. versjon av Programkode 1.1.5 er dette gjort og det er også lagt inn kode som gjør at hvis den største verdien forekommer flere steder, er det posisjonen til den første av dem som returneres.

  public static int maks(int[] a)  // versjon 3 av maks-metoden
  {
    if (a.length < 1)
      throw new java.util.NoSuchElementException("a er tom");

    int sist = a.length - 1;       // siste posisjon i tabellen
    int m = 0;                     // indeks til største verdi
    int maksverdi = a[0];          // største verdi
    int temp = a[sist];            // tar vare på siste verdi
    a[sist] = 0x7fffffff;          // legger tallet 2147483647 sist

    for (int i = 0; ; i++)         // i starter med 1
      if (a[i] >= maksverdi)       // denne blir sann til slutt
      {
        if (i == sist)             // sjekker om vi er ferdige
        {
          a[sist] = temp;          // legger siste verdi tilbake
          return temp > maksverdi ? sist : m;   // er siste størst?
        }
        else if (a[i] > maksverdi)
        {
          maksverdi = a[i];        // maksverdi oppdateres
          m = i;                   // m oppdateres
        }
      }
  } // maks  

Oppgave 5

  int[] a = {8,3,5,7,9,6,10,2,1,4}, b = {};  // to tabeller    

  OptionalInt resultat1 = maksverdi(a);

  if (resultat1.isPresent()) System.out.println(resultat1.getAsInt());
  else System.out.println("Ingen verdi!");

  maksverdi(a).ifPresent(System.out::println);  // en alternativ måte

  OptionalInt resultat2 = maksverdi(b);

  if (resultat2.isPresent()) System.out.println(resultat2.getAsInt());
  else System.out.println("Ingen verdi!");

  // Metoden int orElse(int other) gir verdien hvis den finnes
  // og det vi setter inn som other hvis den ikke finnes.
  // Det kan brukes slik:

  System.out.println(maksverdi(a).orElse(-1));  // utskrift: 10
  System.out.println(maksverdi(b).orElse(-1));  // utskrift: -1