Mit Rekursion zu erhöhen, die Basis für seine exponent - C++
Möchte ich einfach nur code zu schreiben, macht Gebrauch von Rekursion von Funktionen, um eine Basis für seine macht. Ich weiß, dass die Rekursion ist nicht die richtige Weg, Dinge zu tun, in C++, aber ich will einfach nur, um zu erkunden das Konzept ein wenig. Das Programm fragt den Benutzer nach einer Basis und einem Exponenten und dann die Konsole outs die Antwort. Hier ist das Programm, das ich geschrieben habe:
#include <iostream>
#include <math.h>
using namespace std;
int raisingTo(int, int);
int main()
{
int base, exponent;
cout << "Enter base value: ";
cin >> base;
cout << "Enter exponent value: ";
cin >> exponent;
int answer = raisingTo(base, exponent);
cout << "The answer is: " << answer << endl;
char response;
cin >> response;
return 0;
}
int raisingTo(int base, int exponent)
{
if (exponent > 0)
return 1;
else if (exponent = 0)
{
int answer = (int) pow((double)base, raisingTo(base, (exponent - 1)));
return answer;
}
}
Das komische ist, wenn ich dieses Programm ausführen, es hält die Rücksendung der Antwort als '1'! Kann mir bitte jemand helfen dazu?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie 3 wesentliche Probleme:
==
als=
ist eine Zuordnung nicht vergleichen.2^4 = 2 * 2^3
;2^3 = 2 * 2^2
;2^2 = 2 * 2^1
;2^1 = 2 * 2^0
und2^0 = 1
.Machen es zu einem tatsächlichen C++ - Antwort – dies ist die Art von Aufgabe, bei der Sie überlegen, so dass es eine template-Funktion, wie das funktionieren sollte mit jeder Art von Nummer geben.
Rekursion ist in der Tat eine gute Idee, aber nur wenn Sie nutzen die Vorteile, die es bieten kann: Sie können vermeiden, dass einige der Multiplikationen durch ausklammern von niedrigen zahlen der exponent.
Beispiel, wie viele Berechnung diese sparen können: angenommen, Sie wollen, um eine Zahl auf 19. Das ist 18 Multiplikationen, wenn Sie die naive loop-ähnlichen Ansatz. Mit dieser Lösung, was passiert ist
Wurde nur 1+1+2+2 = 6 Multiplikationen, 1/3 der notwendigen Menge für die loop-like Ansatz! Beachten Sie jedoch, dass dies nicht notwendigerweise bedeutet, der code wird viel schneller ausführen, da die überprüfung von Faktoren, die auch einige Zeit in Anspruch nimmt. Insbesondere die
%3
aufunsigned
s wohl nicht schneller als die Multiplikation aufint
s, also fürNumT==int
es ist nicht wirklich clever an alle. Aber es ist clever für die teureren floating-point-Typen,complex
, nicht zu sprechen von linearer algebra matrix-Typen, für die Multiplikation kann extrem teuer sein.%
ist teurer als die Multiplikation für alle Arten, ob es überhaupt definiert ist. Plus, Sie brauchen es nicht.unsigned
(meine Funktion nie benötigt, um es zu tun auf andere Art, als dies ist der exponent) ist sicherlich auch nicht teurer als jede Multiplikation, wie es ist, entspricht der Bitmaske&1U
, so dass die==0
können optimiert werden, dass ein einzelner Computer-Anweisung, die von jeder optimierende compiler; ziemlich sicher. Die%3
, wie ich schon bemerkt habe, ist nicht ganz so trivial, sollte aber trotzdem noch einigermaßen schnell. Außerdem ist es eher selten genannt (die nur drei mal in meinem Beispiel), obwohl man argumentieren kann, dass die brances, die es vermeiden, diese sind wahrscheinlich das teuerste, was in meinem code...*2
ist eine bit-Verschiebung. Und%3
ist VIEL teurer als*3
für Integrale Typen, und nicht einmal erlaubt, für floating-point-oder komplexe Typen (Ihre Beispiele, wenn Sie dachte, es wäre schneller). Ich sehe, was du meinst, über den Unterschied in der Art zwischenexponent
undbase
aber ich denke meine Lösung ist, nur so wenige multipliziert, derbase
geben, und keine division der exponent-Typ. Und ist tail-rekursiv.Dein problem liegt hier
Erstens, Sie haben invertiert den bedingten (wenn der exponent gleich null ist, sollte es wieder), zweitens, Sie sind zuweisen und nicht zu vergleichen mit der zweiten
if
.int answer = (int) pow((double)base, raisingTo(base, (exponent - 1)));
ist auch kaputt.else if (exponent = 0)
ist ein sehr grober Fehler!. Weil es die Zuordnung und das Ergebnis dieser operation ist die Rechte Seite den Wert in diesem Fall0
also das else if Abschnitt werden nie ausgeführt. Zum Vergleich==
verwendet werden soll.Hier eine version mit besserer Komplexität (
O(lg exponent)
stattO(exponent)
), die sich konzeptionell ähnlich leftroundabout version.Nutzt Sie auch die tail-Rekursion, die in der Regel führt zu besser optimierten Maschinen-code.
Hier ist ein Reiniger Erklärung mit O(log n) Komplexität
Dieser Algorithmus arbeitet auf folgende einfachen Regeln der exponent
Somit auf jeder Ebene, Wert von n ist entweder die Hälfte von dem, was es war, oder es ist etwas kleiner als n ist . So ist die deppest die Rekursion wird jemals wieder
1+log n
EbenenInformationen Quelle