JavaRush /Java Blog /Random-TK /Java-da gaýtalanma

Java-da gaýtalanma

Toparda çap edildi
Gaýtalanmagyň nämedigine düşünmek üçin gaýtalanmanyň nämedigine düşünmeli. Aslynda, beýle funksiýalara düşünmekde kyn zat ýok, oňa diňe bir gezek gowy düşünmeli. Programmirleme barada aýdylanda bolsa amal ediň. Java-da gaýtalanma - 1Gaýtalama diňe bir programmirlemekde däl, eýsem hakyky durmuşda-da bolýar. Eliňizde aýna alyň we başga aýnanyň öňünde duruň. Yzygiderliligiň şöhlelenmesi şöhlelenmede we ş.m. Tükeniksiz köp sanly pikirlenmäni görersiňiz. “” Er togalagy gününe bagyşlanýar ... ” makalasynda “hakyky” gaýtalanma barada has giňişleýin maglumat alyp bilersiňiz . Geliň, hakyky dünýäden programmistiň gündelik durmuşyna gaýdyp geleliň. Pleönekeý kesgitleme: Java-da gaýtalanýan funksiýalar özlerini çagyrýan funksiýalardyr. Size gaty ýönekeý we gaty zyýanly mysal getireýin:
public void recursionFucn() {
    System.out.println("Привет, JavaRush!");
    recursionFucn();
}
Näme üçin zyýanly? Özüňiz barlamagy maslahat berýärin! Bu başdan geçirmäni kabul etmek kararyna gelseňiz (we programmaçy! seresap boluň. Meseläni çözmäge şeýle çemeleşmäniň nirede, haçan we näme üçin dogrydygyna düşünmeli we funksiýaňyzyň programmanyň ýerine ýetirilişini “Groundhog Day” -a öwürmeýändigine göz ýetirmeli. Gaýtalanma düşünmek üçin ýene iki möhüm kesgitleme bar:
  • Gaýtalanma esaslary - gaýtalanýan jaňlar blokundan çykmagyň şerti - gaýtalanma jaň etmegiň zerurlygy bolmadyk şertlerde meseläniň esasy çözgüdi.
  • Gaýtalama ädimi , parametrler üýtgedilende bir funksiýanyň özüni çagyrmagydyr.
Gaýtalanýan funksiýany ulanmagyň nusgawy mysaly, sanyň faktoryny hasaplamakdyr. Forgatdan çykaran bolsaňyz, size ýatladýaryn: polo positiveitel bitewi faktoryň N(N! Diýlip görkezilýär) sanlaryň önümidir 1 до N: N! = 1 * 2 * 3 * … (N - 1) * N. Theeri gelende aýtsak, kesgitleme boýunça nol faktory 1-e deňdir. Şonuň üçin faktory islendik polo positiveitel bitewi we nol üçin tapyp bolar (matematikanyň dilinde - negatiw däl bitewi sanlar toplumy ýa-da tebigy sanlar toplumy üçin we nol). Aýlawlary ulanyp faktorial programma edip biljekdigiňize düşünýärsiňiz öýdýärin. Aslynda, bu meseläni çözmek üçin gaýtalanmaýan usul:
private int fact(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result = result * i;
    }
    return result;
}
Geliň, sanyň pozitiw we bitewi bir barlygyny, nol üçin aýratyn çek goşalyň.
private int fact(int n) {
    if (n < 0) {
        System.out.println("Зачем тебе факториал из отрицательного числа?");
         return null;
    }
    int result = 1;
    if (n == 0) {
        return result;
    }
    for (int i = 1; i <= n; i++) {
        result = result * i;
    }
    return result;
}
Indi bu meseläni yzygiderli çözmek üçin usul koduny bererin:
private int factorial(int n) {
    int result = 1;
    if (n == 1 || n == 0) {
        return result;
    }
    result = n * factorial(n-1);
    return result;
}
Çagyryşlaryň netijelerine seredeliň:
System.out.println(factorial(0));
System.out.println(factorial(1));
System.out.println(factorial(2));
System.out.println(factorial(3));
System.out.println(factorial(4));
System.out.println(factorial(5));
System.out.println(factorial(6));
Garaşylýan bahalary alýarys:
1
1
2
6
24
120
720
Geliň, gowy çykyş goşalyň we has köp sanly faktory hasaplalyň:
private int factorial(int n) {
    int result = 1;

    if (n == 0) {
        System.out.print(" = ");
        return result;
    }
    if (n == 1) {
        System.out.print(" * 1 = ");
        return result;
    }

    System.out.print(n);
    if (n != 2) {
        System.out.print(" * ");
    }

    result = n * factorial(n-1);
    return result;
}


System.out.println(factorial(15) + "!");
Alýarys: 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 = 1 307 674 368 000! Bu ýagdaýda gaýtalanýan funksiýany ulanmak dogry we ygtybarlydyr. Gaýtalanýan blokdan çykmagyň şertini anyk kesgitledik we ýetip boljakdygyna ynanýarys: negatiw däl bitewi san girizýäris, eger san nola ýa-da birine deň bolsa, san köp bolsa, netijäni gaýtaryp berýäris , netijäni sanyň funksiýasy bilen köpeldýäris n-1. Üç faktory mysal hökmünde ulanmak:
factorial(3) внутри себя выполнит следующее:
	result = 3 * factorial(2); (рекурсивный вызов)

	factorial(2) внутри себя выполнит следующее:
		result = 2 * factorial(1); (рекурсивный вызов)

		factorial(1) вернет 1 (базис рекурсии)

	factorial(2) вернет 2 * 1

factorial(3) вернет 3 * 2 * 1
Ulanyşda seresaplylyk barada: bu funksiýanyň gowşak tarapy näme? Bir usuly parametr hökmünde negatiw san berseňiz, barlaň
if (n == 1 || n == 0) {
    return result;
}
manysy ýok we özümizi çagyrmagyň tükeniksiz aýlawyna çykarys. Ativaramazlyk üçin çek goşmaly:
if (n < 0) {
	System.out.println(«Зачем тебе факториал отрицательного числа?»);
	return null;
}
Hemmesi gowy bolar. Bir usulyň beýlekisinden artykmaçlygy näme? Uly tapawut bar ýaly däl, aslynda köp gaýtalanýan jaňlar öndürijilige we ýadyň sarp edilmegine ýaramaz täsir eder: jaň nokady gözegçiliksiz diýen ýaly çeşme we şol bir gaýtalanýan funksiýany çagyrmak üçin dürli şertlerde, bu çeşme bilen baglanyşykly problemalary alyp bileris ýa-da alyp bilmeris. Gaýtalama (sikller for-each) ulanyp çözülen meseleleriň hemmesi diýen ýaly yzygiderli çözülip bilner. Gaýtalanmagyň artykmaçlygy okamak we ýazmak aňsatlygy, ýokardaky kemçilikleri barada gürleşdik: “özüňi aýakdan atmak” mümkinçiligi hyýaly däl. “Çylşyrymly gaýtalanma” diýilýän zady ulananyňyzda has seresap bolmalysyňyz: Funksiýa funksiýa diýilýän A()funksiýa diýer . Şeýle problemalary çözmek gaýtalanmagyň nähili işleýändigine doly düşünmegi talap edýär. Şeýle meseläniň mysaly: bahasyny hasaplamak . Aboveokarda belläp geçişimiz ýaly zawod, negatiw däl bitewi sanlar toplumynda kesgitlenýär. Ahyrynda çözgüt koduny bererin. Çylşyrymly gaýtalanma iki usuldan ybarat bolar: B()A()x^n/(n!)
private double calculate(int x, int n) {
    return power(x, n) / n;
}
private double power(int x, int n) {
    if (n == 1) return x;
    return x * calculate(x, n - 1);
}
Gaýtalanma girmek üçin bir usul diýilýär calculate, powerbu bolsa öz gezeginde usul diýýär calculate. Kuwwat usulynda gaýtalanma esaslaryny kesgitledik:
if (n == 1) return x;
Gaýtalama ädimi hem şol ýerde kesgitlenýär:
return x * calculate(x, n - 1);
Giriş maglumatlarynyň dogrulygyna çek goşmak galýar:
  • Noldan başga islendik san nolyň güýjüne deňdir 1. Eger n = 0bar bolsa n! = 1. Ony yzyna gaýtarmaly 1.
  • Islendik güýje nol nola deňdir.
  • Görnüşdäki näbellilik hasaplamarys 0^0we giriş maglumatlaryny nädogry diýip kabul ederis.
Allhli barlaglar bilen usullar şeýle bolar:
private double calculate(int x, int n) throws ArithmeticException {
    if (x == 0 && n == 0) {
        throw new ArithmeticException("Невалидные входные данные: Неопределенность типа 0^0");
    }

    if (n < 0) {
        throw new ArithmeticException("Невалидные входные данные: Факториал из отрицательного числа!");
    }

    if (n == 0) {
        return 1;
    }

    if (x == 0) {
        return 0;
    }

    if (x == 0) {
        return 0;
    }
    return power(x, n) / n;
}

private double power(int x, int n) {
    if (n == 1) return x;
    return x * calculate(x, n - 1);
}
Bir funksiýa jaň edeniňizde, ýalňyşlygy tutmagy ýatdan çykarmaly dälsiňiz:
try {
    System.out.println(calculate(x, n));
} catch (ArithmeticException e) {
    System.out.println(e.getMessage());
}
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION