Prawo Murphy'ego: Tranzystor zabezpieczony przez szybko działający bezpiecznik, zabezpieczy go - paląc się w pierwszej kolejności.
Część 3.6. Przykłady programów Javy

1. Parametry metody main

Zaczniemy od prostego programu, którego jedynym zadaniem będzie wyświetlenie parametrów. Zastanawiałeś się zapewne po co zawsze w metodzie main podajemy parametr String args[]? Jest to tablica parametrów przekazanych do programu podczas jego uruchamiania. Każdy łańcuch znaków, zakończony spacją, podany po nazwie uruchamianego programu wstawiany jest do tej tablicy na kolejną pozycję. W ten sposób możemy uruchamianemu programowi przekazać pewne dane już w momencie uruchomienia.

class Parametry
{ public static void main (String args[])
  { for (int i = 0; i < args.length; i++)
        System.out.println ("args[" + i + "] = " + args[i]);
  }
}

Po napisaniu tego programu uruchom go w następujący sposób:

java  Parametry  ala ola ela

Program powinien na ekranie wyświetlić:

args[0] = ala
args[1] = ola
args[2] = ela

2. Wczytywanie liczb całkowitych i rzeczywistych z klawiatury

Kolejny program pokazuje, jak w Javie można wczytywać dane z klawiatury. Program służy do wczytywania pary liczb: najpierw całkowitej, a następnie rzeczywistej. Wczytywanie powtarzane jest do moment, gdy choć jedna z wprowadzonych liczb będzie zerem.

Wczytywanie danych z klawiatury nie należy do czynności prostych. Wymaga użycia aż trzech klas: InputStreamReader, której instancją jest System.in, oraz BufferedReader i StreamTokenizer. Wzzystkie one zadeklarowane sa w pakiecie java.io, stąd konieczność dołączenia tego pakietu do naszego programu.

//dołączenie pakietu java.io
import java.io.*;

public class CzytanieLiczb
{ public static void main (String args[])
  { int    a = 1;
    double b = 1;
    // deklaracja obiektów niezbędnych do wczytywania danych z klawiatury
    Reader          r   = new BufferedReader (new InputStreamReader(System.in));
    StreamTokenizer inp = new StreamTokenizer(r);
      
    // blok try jest konieczny ze względu na użycie metody nextToken()
    // bez użycia tego bloku wystąpiłby błąd kompilacji
    try
    {  while (a != 0 && b != 0)
       {  System.out.print("\nPodaj liczbę całkowitą: ");
          while (inp.nextToken() != StreamTokenizer.TT_NUMBER)
                // wczytywanie do momentu otrzymania poprawnej liczby całkwitej
                { System.out.println("Blad wprowadzania\nPodaj liczbe całkowita:"); }
           a = (int) inp.nval;             // konwersja danych na typ całkowity

           System.out.print("Podaj liczbe rzeczywista: ");
           while (inp.nextToken() != StreamTokenizer.TT_NUMBER)
                // wczytywanie do momentu otrzymania poprawnej liczby rzeczywistej
                { System.out.println("Blad wprowadzania\nPodaj liczbe rzeczywista:"); }
           b = (double) inp.nval;          // konwersja danych na typ rzeczywisty

           System.out.println("Liczba calkowita = " + a + ", liczba rzeczywista = " + b);
       }
    }

    // konieczne jako zamkniecie bloku try
    catch (IOException e)
    { ; }
  }
}

Zobacz kilka przykładów działania tego programu. Zwróć uwagę na różne możliwości wpisywania danych. Program zawsze czyta cały wiersz, a potem dopiero dzieli go na tokeny (element, liczby, ...).

3. Obliczanie silni

Napiszemy teraz program obliczający i wyświetlający silnię (n! = 1*2*3*...*n) liczb od 0 do 20. Program sam w sobie dość banalny. Zwróć jednak uwagę na rekurencyjne wywołanie metody silnia.
class Silnia
{ public static void main (String args[])
  { long x;

    for (int n=0 ; n<=20 ; n++)
    { x = silnia(n);
      System.out.println (n + "! = " + x);
    }
  }

  static long silnia (int n)
  { long wynik;

    // metoda wywołuje sama siebie ze zmniejszoną o 1 wartością argumentu
    // aż do momentu, dgy przekazany argument będzie <= 1
    if (n > 1) wynik = silnia( n-1) * n;
    else       wynik = 1;
    return wynik;
  }
}

4. Największy wspólny podzielnik i najmniejsza wspólna wielokrotność

Ten program wczytuje parę liczb naturalnych i oblicza ich największy wspólny podzielnik i najmniejszą wspólną wielokrotność. Zwróć uwagę, że do wczytania obu liczb naturalnych wykorzystywana jest jedna i ta sama metoda: czyni to program bardziej zwięzłym, czytelnym i efektywniejszym.
import java.io.*;

class NwwNwp
{ public static void main (String args[])
  { int n1, n2, n;

    n1 = LiczbaNaturalna();
    n2 = LiczbaNaturalna();

    if (n1 > n2)
	{ n  = n1;
      n1 = n2;
      n2 = n;
	}
    n = n2;

    while (n % n1 !=0)
    { n += n2;
    }
    System.out.println("NWW = " + n);

    while (n1 != n2)
    { if (n1 > n2)  n1 -= n2;
      else          n2 -= n1;
    }
    System.out.println("NWP = " + n1);
  }

  static int LiczbaNaturalna()
  { int n = 0;
    Reader          r   = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer inp = new StreamTokenizer(r);
      
    try
    {  while (n <= 0)
       {  System.out.print("Podaj liczbe naturalna: ");
          while (inp.nextToken() != StreamTokenizer.TT_NUMBER)
               { System.out.println("Liczba musi byc > 0\nPodaj liczbe naturalna:"); }
          n = (int) inp.nval;
       }
    }

    catch (IOException e)
    { ; }

    return n;
  }
}

5. Sortowanie tablicy jednowymiarowej

Zadaniem kolejnego programu jest posortowanie wektora (tablicy jedno wymiarowej) liczb całkowitych. Program najpierw wczytuje rozmiar wektora, a następnie wszystkie jego elementy. Po zakończeniu wczytywania następuje sortowanie wektora i wyswietlenie wszystkich jego elementów.

Program wykorzystuje znaną już metodę rekurencyjną w metodzie sort oraz metodę służącą do wczytywania danych z klawiatury. Zwróć szczególną uwagę na dynamiczne przydzielanie pamięci dla wektora danych: przydział pamięci następuje dopiero po wczytaniu ilości elementów wektora, a tworzony wektor będzie zajmował dokładnie tyle pamięci, ile jest konieczne do przechowania podanej ilości elementów.

import java.io.*;

class SortowanieTablicy
{ static int Len;
  static int T[];
  
  public static void main (String args[])
  { Len = CzytajLiczbe(-1);
    T = new int [Len];

    System.out.println("Podaj elementy tablicy");

    for (int i=0 ; i<Len ; i++) 
    { T[i] = CzytajLiczbe(i);
    }

    sort(0, Len-1);

    System.out.println("\n\nPosortowana tablica:");
    for (int i=0 ; i<Len ; i++) 
    { System.out.print(T[i] + ", ");
    }
  }

  static int CzytajLiczbe(int i)
  { int n = 0;
    String s;
    Reader          r   = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer inp = new StreamTokenizer(r);
      
    // ustawienie wyświetlanego komunikatu w zależności od tego, co jest wczytywane:
    // inny dla rozmiaru wektora i inny dla jego elementów
    if (i == -1) s = new String("Podaj ilosc elementów w tablicy: ");
    else         s = new String("Podaj " + i + " element tablicy: ");
    try
    {  while (true)
       {  System.out.print(s);
          while (inp.nextToken() != StreamTokenizer.TT_NUMBER)
               { System.out.println("Blad! " + s); }
          n = (int) inp.nval;
          // dla rozmiaru wektora wartość musi być dodatnia
          // dla elementów wektora - może być dowolną liczbą całkowitą
          if (i == -1  &&  n > 0  ||  i >= 0) break;
       }
    }
    catch (IOException e)
    {;}

    return n;
  }

  static void sort(int min, int max)
  { int i = min , j = max, x, y = (int)((min+max)/2);
    x = T[y];

    do
    { while (T[i] < x  &&  i < max)	i++;
      while (x < T[j]  &&  j > 0 )	j--;
      if (i <= j)
      { y    = T[i];
        T[i] = T[j];
        T[j] = y;
        i++;
        j--;
      }
    } while (i <= j);

    // rekurencyjne wywoływanie metody, aż do zakończenia sortowania
    if (min < j) sort(min, j);
    if (i < max) sort(i, max);
  }
}

6. Sumowanie wierszy i kolumn tablicy dwuwymiarowej

Na zakończenie program operujący na macierzy (tablicy dwuwymiarowej). Aby uniknąć wprowadzania wielu danych elementy macierzy są generowane losowo: służy do tego metoda Math.random(), która generuje liczby losowe z zakresu [0, 1>. Po wygenerowaniu wszystkich elementów macierzy następuje jej wyświetlenie z jednoczesnym sumowaniem wartości w każdym wierszu i każdej kolumnie.
public class Tablica2D
{  public static void main (String args[])
   {  int x, y, T[][] = new int [5][5];
      String txt;
      int suma;

      // generowanie elementów macierzy: liczb losowych z przedziału [0, 500]
      for (y = 0 ; y <= 4 ; y++)
          for (x = 0 ; x <= 4 ; x++)
              T[x][y] = (int) (Math.round(Math.random() * 500));

      // wyświetlanie macierzy z sumowaniem wartości w wierszach
      for (y = 0 ; y <= 4 ; y++)
      {  suma = 0;
         for (x = 0 ; x <= 4 ; x++)		
         {  suma += T[x][y];
            txt = Integer.toString (T[x][y]);     // konwersja liczby na łańcuch znaków

            // pętla uzupełniająca wyświetlany tekst spacjami z przodu:
            // ma to zagwarantować jednakową ilość miejsc dla każdej liczby
            while (txt.length() < 5)
                  { txt = " " + txt; }
            System.out.print (txt);
         }
         txt = Integer.toString (suma);           // konwersja liczby na łańcuch znaków

        // pętla uzupełniająca wyświetlany tekst spacjami z przodu:
        // ma to zagwarantować jednakową ilość miejsc dla każdej liczby
         while (txt.length() < 5)
                { txt = " " + txt; }
         System.out.println ("| " + txt);
      }

      System.out.println ("--------------------------");

      // sumowanie wartości w kolumnach macierzy
      for (x = 0 ; x <= 4 ; x++)
      {  suma = 0;
         for (y = 0 ; y <= 4 ; y++)		
         {  suma += T[x][y];
         }
         txt = Integer.toString (suma);             // konwersja liczby na łańcuch znaków

        // pętla uzupełniająca wyświetlany tekst spacjami z przodu:
        // ma to zagwarantować jednakową ilość miejsc dla każdej liczby
         while (txt.length() < 5)
              {txt = " " + txt;}
         System.out.print (txt);
      }
   }
}
« wstecz   dalej »