/*
Datei............: Aufg1130.java
Projekt..........: Einführung in die Java-Programmierung
Erstellt.........: 22.11.97, Guido Krüger
Geändert.........: --
Aufgabe..........: Musterlösung zu Aufgabe 11.30
Kommentare.......:

Die Hauptaufgabe in dieser Lösung wird von der Klasse DecodeSupporter
erledigt. Sie speichert den Originalstring, ermittelt die 
Buchstabenhäufigkeiten und erstellt daraus eine Tauschtabelle.
Weiterhin bietet die Klasse die Möglichkeit, den Originalstring,
die Tauschtabelle und den veränderten String auszugeben und 
erlaubt es, Einträge in der Tauschtabelle zu verändern. Das
Rahmenprogramm der Klasse Aufg1130 stellt lediglich die 
Benutzerschnittstelle dar. Weitere Hinweise zur Arbeitsweise
der Methoden finden sich in den Kommentaren im Quelltext.

Nach einigem Probieren kann man mit Hilfe dieses Programms die
in der Aufgabe angegebene Nachricht entschlüsseln und erhält den
ersten Satz aus Kafka's "Die Verwandlung".
*/
import java.util.*;
import java.io.*;

public class Aufg1130
{
  public static void main(String args[])
  {
	String s = "";
    BufferedReader din = new BufferedReader(
						 new InputStreamReader(System.in));
	s += "rle gnagon ermer aisae mongase rue usnuhigas tnraumas ";
	s += "anwrchta, frsd an eich is eaisam batt zu aisam usgahauanas ";
	s += "usgaziafan vanwrsdalt.";
	DecodeSupporter supp = new DecodeSupporter(s);
	while (true) {
	  supp.print();
	  System.out.println();
	  System.out.print(
		"Welche beiden Stellen sollen vertauscht werden (0=Ende)? "
	  );
	  try {
		String inpbuf = din.readLine();
		StringTokenizer st = new StringTokenizer(inpbuf);
		int swap1 = Integer.parseInt(st.nextToken());
		if (swap1 == 0) {
		  break;
		}
		int swap2 = Integer.parseInt(st.nextToken());
		supp.swap(swap1, swap2);
		System.out.println();
	  } catch (IOException e) {
		System.out.println(e.toString());
		break;
	  }
	}
  }
}

class DecodeSupporter
{
  //--- Instanzmerkmale -----------------------------
  private String buf;			//Originaltext
  private char swaptab[][];		//Tauschtabelle

  //--- Öffentliche Methoden ------------------------
  public DecodeSupporter(String s)
  {
	buf = s;
	prepare();
  }

  /**
   * Gibt den Originaltext, den bearbeiteten Text und die Tauschtabelle
   * auf dem Bildschirm aus.
   */
  public void print()
  {
	System.out.println("--- Originaltext ------------------");
	System.out.println(buf);
	System.out.println("--- Tauschtabelle -----------------");
	/*
	for (int i = 0; i <= 1; ++i) {
	  for (int j = 0; j < swaptab.length; ++j) {
		System.out.print((i == 0 ? (j+1) + "." : "  ") + swaptab[j][i] + "  ");
	  }
	  System.out.println();
	}
	*/
	for (int i = 0; i < swaptab.length; ++i) {
	  System.out.print(
        (i+1) + "." + swaptab[i][0] + "->" + swaptab[i][1] + " "
      );
	}
	System.out.println();
	System.out.println("--- Bearbeitet --------------------");
	printDecodedBuf();
  }

  /**
   * Vertauscht die Zeichen an Position swap1 und swap2 der 
   * Tauschtabelle.
   */
  public void swap(int swap1, int swap2)
  {
	if (swap1 >= 1 && swap1 <= swaptab.length && 
        swap2 >= 1 && swap2 <= swaptab.length) {
	  char tmp = swaptab[swap1 - 1][1];
	  swaptab[swap1 - 1][1] = swaptab[swap2 - 1][1];
	  swaptab[swap2 - 1][1] = tmp;
	}
  }

  //--- Private Methoden ------------------------------
  /**
   * Diese Methode wird am Ende des Konstruktors aufgerufen und
   * dient der Vorbereitung aller weiteren Aktivitäten. Es werden
   * folgende Schritte ausgeführt:
   *
   * 1. Die Häufigkeit jedes einzelnen Zeichens wird gezählt.
   * 2. Zum Sortieren des Häufigkeitsarrays wird ein Schattenarray
   *    erstellt, daß an der korrespondierenden Indexposition das
   *    Zeichen enthält, dessen Häufigkeit im Häufigkeitsarray
   *    festgehelten wird.
   * 3. Anschließend werden beide Arrays (synchron) nach absteigender
   *    Häufigkeit sortiert. Dazu wird ein einfaches Selectionsort-
   *    Verfahren verwendet.
   * 4. Die Größe der Tauschtabelle wird bestimmt.
   * 5. Die Tauschtabelle wird erstellt und gefüllt.
   */
  private void prepare()
  {
	//Zeichenhäufigkeit zählen
	int count[] = new int['z' - 'a' + 1];
	for (int i = 0; i < buf.length(); ++i) {
	  char c = buf.charAt(i);
	  if (c >= 'a' && c <= 'z') {
		++count[c - 'a'];
	  }
	}
	//Schattenarray zum Sortieren erstellen
	char chars[] = new char['z' - 'a' + 1];
	for (char c = 0; c <= 'z' - 'a'; ++c) {
	  chars[c] = (char)(c + 'a');
	}
	//Arrays sortieren
	for (char c1 = 0; c1 < 'z' - 'a'; ++c1) {
	  char maxpos = (char)(c1 + 1);
	  for (char c2 = (char)(c1 + 2); c2 <= 'z' - 'a'; ++c2) {
		if (count[c2] > count[maxpos]) {
		  maxpos = c2;
		}
	  }
	  if (count[maxpos] > count[c1]) {
		int itmp = count[c1];
		count[c1] = count[maxpos];
		count[maxpos] = itmp;
		char ctmp = chars[c1];
		chars[c1] = chars[maxpos];
		chars[maxpos] = ctmp;
	  }
	}
	//Größe der Tauschtabelle bestimmen
	int cnt = 0;
	for (int i = 0; i <= 'z' - 'a'; ++i) {
	  if (cnt < 5 || count[i - 1] == count[i]) {
		++cnt;
	  } else {
		break;
	  }
	}
	//Tauschtabelle erstellen
	swaptab = new char[cnt][2];
	for (int i = 0; i < cnt; ++i) {
	  swaptab[i][0] = swaptab[i][1] = chars[i];
	}
  }

  /**
   * Gibt den dekodierten Puffer aus. Dazu wird für jedes Element des
   * Originalstrings in der Tauschtabelle nachgeschlagen und das 
   * Zeichen, sofern vorhanden, gegen das Tauschzeichen ausgewechselt.
   * Ist das Zeichen nicht in der Tauschtabelle, wird das Originalzeichen
   * des Puffers an dieser Stelle ausgegeben.
   */
  private void printDecodedBuf()
  {
	for (int i = 0; i < buf.length(); ++i) {
	  char c = buf.charAt(i);
	  boolean swapped = false;
	  for (int j = 0; j < swaptab.length; ++j) {
		if (swaptab[j][0] == c) {
		  System.out.print(swaptab[j][1]);
		  swapped = true;
		  break;
		}
	  }
	  if (!swapped) {
		System.out.print(c);
	  }
	}
	System.out.println();
  }
}

