Gyakorlati alapok II.

Rekurzió

 

Végtelen rekurzió

 

Bevezetésképpen nézzük meg az előző fejezet faktoriális-számításának már ismertetett, rekurzív kódját:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static int faktorialis (int bemenetiAdat){
    if (bemenetiAdat <= 1){
        return 1;
    }
        return bemenetiAdat * faktorialis(bemenetiAdat-1);
    }

    public static void main(String[] args) {
        System.out.println(faktorialis(5));
        }
    }

 

Végeredmény:

120

 

Mivel a rekurzió önmagát meghívó függvénymegoldás és ennek implementálása viszonylag könnyű, ezért könnyen implementálhatunk végtelen ciklust. A fenti Java-kódban elég csak a megfelelő paraméter-beállításban hibáznunk...

 

bemenetiAdat * faktorialis(bemenetiAdat-1)

 

helyett

 

bemenetiAdat * faktorialis(bemenetiAdat)

 

...hogy  végtelen függvényhívásba kerülve elfogyjon a hívási verem (call stack) számára fenntartott memóriaterület és veremtúlcsordulási hibával (stack overflow error) megszakadjon a program, Eclipse esetén pedig regény hosszúságú hibaüzenetet kapjunk:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
    static int faktorialis (int bemenetiAdat){
    if (bemenetiAdat <= 1){
        return 1;
    }
        return bemenetiAdat * faktorialis(bemenetiAdat);
    }

    public static void main(String[] args) {
        System.out.println(faktorialis(5));
        }
    }

 

Végeredmény:

Exception in thread "main" java.lang.StackOverflowError
at Main.faktorialis(Main.java:93)
at Main.faktorialis(Main.java:93)
at Main.faktorialis(Main.java:93)
at Main.faktorialis(Main.java:93)
at Main.faktorialis(Main.java:93)

...

 

Amint azt a bevezető fejezetben tisztáztuk, nagyon könnyen írhatunk végtelen rekurziót olyan módon, hogy nem teszünk a kódba belső szabályozást. Ekkor a függvény korlátlanul fogja hívogatni magát:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
static void vegtelenRekurzio(){
    System.out.println("Végtelen rekurzió");
    vegtelenRekurzio();
}

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

 

Végeredmény:

Végtelen rekurzió
Végtelen rekurzió
Végtelen rekurzió
Végtelen rekurzió
Végtelen rekurzió

...

Exception in thread "main" java.lang.StackOverflowError
at sun.nio.cs.SingleByte.withResult(Unknown Source)
at sun.nio.cs.SingleByte.access$000(Unknown Source)
at sun.nio.cs.SingleByte$Encoder.encodeArrayLoop(Unknown Source)
at sun.nio.cs.SingleByte$Encoder.encodeLoop(Unknown Source)
at java.nio.charset.CharsetEncoder.encode(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at java.io.PrintStream.print(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at Main.vegtelenRekurzio(Main.java:5)
at Main.vegtelenRekurzio(Main.java:6)

...

A kiírás egy ideig fut, de a veremmemória megtelése miatt hibaüzenettel garantáltan le fog állni.