Direkt zum Hauptbereich

Euklidischer Algorithmus in Java

Einleitung

Ein bekannter Algorithmus zum Berechnen des größten gemeinsamen Teilers (kurz: ggT), ist der euklidische Algorithmus und in diesem Artikel soll genau dieser Algorithmus in Java nachkonstruiert werden.

Main.java

Auch dieses Mal wird wieder das String-Array args aus der main-Funktion benutzt um die Benutzeingabe abzufragen. Da dieses Mal keine zusätzlichen Bibliotheken benötigt werden, beginne ich mit gleich mit der Verarbeitung der Benutzeingabe:

if (args.length == 2) {
    char[] first_number = args[0].toCharArray();
    char[] second_number = args[1].toCharArray();
    if (check_number(first_number) == true) {
        if (check_number(second_number) == true) {}
    }
}

Auch in diesem Code habe ich das String-Array in ein Char-Array umgeformt, damit die einzelnen Character in der check_number-Funktion gelesen werden können:

if (((int)c < 48 || (int)c > 57) && c != '+' && c != '-') {
    valid_number = false;
    break;
}

Zuerst soll in der Funktion überprüft werden, ob der einzelne Character eine Zahl zwischen 0 und 9, ein Plus oder ein Minus ist. Sollte das nicht der Fall sein, ist der Character und somit die gesamte Eingabe ungültig.

if (counter > 0 && (c == '+' || c == '-')) {
    valid_number = false;
    break;
}

Nun wird überprüft, ob ein Plus oder ein Minus nicht zu Beginn der Zahl steht. Trifft dieser Fall ein, ist die Eingabe ebenfalls ungültig. Die nächste und auch letzte if-Abfrage verändert das Vorzeichen vom Minus zum Plus, da beim Herausfinden des ggT das Vorzeichen hier vernachlässigt wird.

if (c == '-') {
    number[counter] = '+';
}

Nachdem nun sichergestellt wurde, dass die Benutzereingabe korrekt ist, werden die char-Arrays in integer umgewandelt, da später noch ein paar Rechnungen durchgeführt werden müssen. Erledigt wird dies wieder in einer separaten Funktion 'convert_char_number_to_integer':

public static int convert_char_number_to_integer(char[] number) {
    return Integer.parseInt(new String(number));
}

Man hätte es wieder unnötig kompliziert gestalten können - dazu kommen wir gleich - doch wie man sieht, habe ich eine bereits existierende Funktion benutzt. Doch zum Lernen wollte ich natürlich das gleiche Resultat selbst konstruieren:

public static int comp_char_number_to_integer(char[] number) {
    int num = 0;
    for (char n : number) {
        num = (num * 10 + (n - 48));
    }
    return num;
}

Innerhalb der for-Schleife wird jeder character zuerst in eine Ganzzahl umgewandelt (n - 48) um danach mit num * 10 verrechnet zu werden. Dabei ist der erste Durchlauf immer num * 10 gleich Null. Da wir nun die beiden Ganzzahlen besitzen, können wir mit dem eigentlichen euklidischen Algorithmus beginnen:

public static int recursive_euklidic_algorithm(int a, int b) {
    if (a == 1 || b == 1 || a == b) {
        if (a == 1) {
            return a;
        }
        return b;
    } else {
        if (a > b) {
            a -= b;
        } else {
            b -= a;
        }
        return recursive_euklidic_algorithm(a, b);
    }
}

Das ist eine rekursive Funktion, was für sehr große Zahlen ein sehr großes Problem werden könnte. Deshalb benötigen wir auch noch eine iterative-Funktion:

public static int iterative_euklidic_algorithm(int a, int b) {
    while (a != b && a != 1 && b != 1) {
        if (a > b) {
            a -= b;
        } else {
            b -= a;
        }
    }
    if (a == 1) {
        return a;
    }
    return b;
}

Das zuvor erwähnte große Problem bei der rekursiven Funktion lässt das Programm zum Absturz bringen, da die Rekursionstiefe überschritten wird. Jedes mal, wenn die Funktion erneut aufgerufen wird, wird neuer Speicher vom Stack benötigt, wessen Größe natürlich begrenzt ist. Es kann sich jedoch auch um einen Ganzzahlüberlauf handeln, da Datentypen wie int eine begrenzte Größe repräsentieren können. Wie groß ein Integer sein darf ist vom Compiler und von der Systemarchitektur abhängig.

Man könnte den Code verbessern und die Anzahl an Rechenschritte signifikant verringern, wenn man die Berechnung mit modulo berechnet. Für die iterative Funktion würde das dementsprechend so aussehen:

while (b != 0) {
    int temp = b;
    b = a % b;
    a = temp;
}
return a;

Der gesamte Code kann wie immer bei meinen GitHub-Account zu finden: /Learning-JAVA/euclideanalgorithm

Kommentare

Beliebte Posts aus diesem Blog

PSE - Python GUI-App

Abb. 1 GitHub: https://github.com/Pulsar7/PSE Zusammenfassung Ich bin kein verifizierter Chemiker oder ein anderweitig akademisch Ausgebildeter, der die angegeben Informationen zum Periodensystem verifizieren kann. Die verwendeten Daten werden unten geschildert. Meine Idee zur Visualisierung ist relativ simpel. Zu jedem Element wird ein Button -Element erstellt worin Basisinformationen zum jeweiligen Element angezeigt werden: Ordnungszahl Masse (u) Symbol Damit das Layout “moderner” aussieht, wollte ich zu Beginn das Modul ttkbootstrap einbinden, was jedoch nicht so geklappt hat, wie ich es mir vorgestellt hatte. Das Periodensystem wird in 11 Serien unterschieden und hierzu werden 11 verschiedene Farben benötigt. Da ich jedoch keinerlei Möglichkeit finden konnte, wie ich Farben zu ttkbootstrap hinzufügen könnte, habe ich das Modul vorerst ausgeschlossen. Update 1.3 Es wurden mehr Informationen zu jedem einzelnen PSE-Element hinzufügt. Damit die Daten auch sinnvoll ges

Palindrome & Java

Einleitung Zu einen der ersten Projekte, die man beim Lernen von Programmiersprachen programmiert, ist ein "Palindrom-Prüfer". Ein Benutzer soll die Möglichkeit haben ein Wort (oder sogar einen ganzen Satz) einzugeben und dann soll das Programm überprüfen, ob es sich bei der Eingabe um ein Palindrom handelt. Genau das wird im Folgenden mit Java behandelt, nur etwas unnötig kompliziert. Main.java Innerhalb der Main.java -Datei werden nun die nötigen Packete eingebunden: import java.util.HashMap; import java.util.Scanner; // for user-input Dann können wir auch schon die Main-Klasse und die main-Funktion definieren: public class Main { public static void main(String[] args) {} } Der Benutzer soll nun die Möglichkeit haben sein Wort als Parameter in der args