Einstieg in Java und OOP
Einstieg in Java und OOP - Das Buch

Zahlenspielereien

1. Verzinsung bis zur Verdoppelung

Um ungefähr abschätzen zu können, wie lange es dauert, bis eine Ausgangsgröße K bei periodischer Verzinsung zu einem bestimmten Zinssatz p aufgedoppelt wird, kann man folgende Formel verwenden:
n = 70 / p
Beispielsweise möchte man wissen, wie lange es dauert, bis sich die Bevölkerungzahl der Erde verdoppelt, wenn die Zahl der Menschen auf der Erde jährlich um 2% zunimmt. Man rechnet hier einfach 70 / 2 = 35. Also gibt es in 35 Jahren demnach doppelt so viele Erdenbürger im Vergleich zu heute.


2. Variablewert zwischen zwei konstanten Werten wechseln

Man stelle sich vor, man benötige in der Programmierung eine Funktion, die zwei feste Zahlenwerte vertauscht. Eine Variable soll auf einen Wert A gesetzt werden, wenn sie den Wert B enthält und umgekehrt. Dafür würde man in der Regel eine if-Anweisung verwenden. Eine andere Möglichkeit wäre die Folgende:
x = A + B - x;
Dies wird zwar nicht dem Prinzip der Strukturierten Programmierung gerecht und man sollte deshalb auch auf die Implementierung dessen verzichten, da es nur schwer lesbar ist ... aber ich finde es nett. :)


3. Zwei Variablenwerte ohne Hilfvariable vertauschen

Normalerweise benötigt man, um die Werte zweier numerischer Variablen zu vertauschen eine zusätzliche Hilfsvariable. Das ganze sieht dann z.B. so aus:
x = 7;
y = 3;

h = x;   // h = 7
x = y;   // x = 3
y = h;   // y = 7
Anschließend steht also dann in x der Wert aus y und umgekehrt. Man kommt allerdings auch ohne diese Hilfvariable h aus. Nämlich folgendermaßen:
x = 7;
y = 3;

x = x - y; // x = 7 - 3 = 4
y = x + y; // y = 4 + 3 = 7
x = y - x; // x = 7 - 4 = 3
Noch rafinierter geht es mit der XOR-Verknüpfung. Damit benötigt man statt wie oben zwei Operatoren (+ und -) nur noch einen Einzigen, nämlich den XOR-Operator. Dazu das selbe Beispiel wie oben nur Dieses - wegen der besseren Lesbarkeit - in Binärdarstellung:
x = 111;
y = 011;
	
x = x XOR y; // x = 111 XOR 011 = 100
y = x XOR y; // y = 100 XOR 011 = 111
x = x XOR y; // x = 100 XOR 111 = 011
Selbiges funktioniert beispielsweise auch mit der Umkehrfunktion von XOR (also NOT XOR) oder entsprechend dem obigen +/- Verfahren auch mit * (Mal) und / (Geteilt). Bei Letzterem darf allerdings weder x noch y den Wert 0 enthalten (Division durch 0!).

Unter Verwendung einer Programmiersprache wie beispielsweise Java lässt sich das Vertauschen von Variablenwerten durch Ausnutzung der Operatorenprioritäten auch mit einer einzigen Anweisung realisieren (In Java steht das ^-Zeichen bzw. das sog. Zirkumflex für den XOR-Operator):
int x = 7;
int y = 3;

x ^= y ^ (y = x);
Oder alternativ:
x += y - (y = x);
4. Rekursive anonyme Funktionen

Das folgende Skript zeigt den Aufruf einer rekusiven anonymen Funktion zur Berechnung der Fakultät von 5 in JavaScript:
var r = 

  function (x) {
    return function (fn) {
      return fn(fn);
    } (function (fn) {
      return x(function (x) {
        return fn(fn)(x);
      });
    });
  }
  (function (rec) {
    return function (n) {
      if (n == 1) return 1;
      else return n * rec(n - 1);
    };
  })(5);
5. Rekursiver Algorithmus zur Permutation

Nachfolgende Java-Klasse zeigt insb. mit der Methode perm() einen recht eleganten, wenn auch inperformanten Algorithmus zur Permutation. Er ist inperformant aufgrund der Rekursion als solche und vor allem weil hier bei jedem Aufruf mit clone() eine tiefe Kopie des Arrays durchgeführt werden muss. Iterative Lösungen bieten üblicherweise eine bessere Performance. Im Übrigen dient die Hilfsmethode swap() zum Vertauschen zweier Werte in einem Array, print() dient zur Ausgabe der Elemente eines Arrays und main() initialisiert zunächst den Array und gibt dann den Anstoß für die Vertauschvorgänge. Solche Tabellen können Sie auch hiermit erzeugen.
public class Permutation {

  private static void swap(
      int[] list, int i, int j) {
    int h = list[i];
    list[i] = list[j];
    list[j] = h;
  }
	
  private static void print(int[] list) {
    for (int x : list) {
      System.out.print(x + " ");
    }
    System.out.println();
  }
	
  static void perm(int[] olist, int n) {

    if (n == 0) {
	  print(olist);
      return;
    }

    int[] list = olist.clone();

    for (int i = 0; true; i++) {
      perm(list, n - 1);
      if (i == n) break;
      swap(list, 
           list.length - n - 1, 
           list.length - n + i);
    }
  }
	
  public static void main(String[] args) {
    int n = 5;
    int[] list = new int[n];
    for (int i = 0; i < list.length; i++)
      list[i] = i + 1;
    perm(list, list.length - 1);
  }
}