Aus meiner Forschung, verstehe ich diese eine rekursive Lösung
gar nicht sein sollte.
Hinweis: Wenn Sie die Rekursion nicht unnötig verwenden, können Sie bestimmte potenzielle Probleme vermeiden (Rekursionsebenen und Stack-Wachstum pro Level), und es ist oft einfacher, den Code zu verstehen.
Schauen wir uns an, was Sie tun. Wenn wir die negativen Zahlen für den Moment zu ignorieren, sind Erzeugen Sie im Grunde die folgende Sequenz (für k = 2, n = 4):
0 0 0 0 0 1 0 0 0 2 0 0
0 0 0 1 0 1 0 1 0 2 0 1
0 0 0 2 0 1 0 2 0 2 0 2
0 0 1 0 0 1 1 0 0 2 1 0
0 0 1 1 0 1 1 1 0 2 1 1
0 0 1 2 0 1 1 2 0 2 1 2
0 0 2 0 0 1 2 0 0 2 2 0
0 0 2 1 0 1 2 1 0 2 2 1
0 0 2 2 0 1 2 2 0 2 2 2
Wenn k 9 wäre, würde man einfach in dezimal werden gezählt. Von allen Kindern, die ich gesehen habe, zu zählen, habe ich noch nie gewusst, dass ich Rekursionen machen kann. ;) Wenn du zurücktrittst und darüber nachdenkst, wie du gelernt hast, große Zahlen zu zählen, solltest du eine viel einfachere Lösung finden .... Aber ich werde das für später speichern.
Wenn Sie in binär zählen würde es wie folgt aussehen:
0 = 000
1 = 001
2 = 010
3 = 011
4 = 100
5 = 101
6 = 110
7 = 111
Oder zählen mit k=1
und n=3
(mit k bis k):
0 = -1 -1 -1 9 = 0 -1 -1 18 = 1 -1 -1
1 = -1 -1 0 10 = 0 -1 0 19 = 1 -1 0
2 = -1 -1 1 11 = 0 -1 1 20 = 1 -1 1
3 = -1 0 -1 12 = 0 0 -1 21 = 1 0 -1
4 = -1 0 0 13 = 0 0 0 22 = 1 0 0
5 = -1 0 1 14 = 0 0 1 23 = 1 0 1
6 = -1 1 -1 15 = 0 1 -1 24 = 1 1 -1
7 = -1 1 0 16 = 0 1 0 25 = 1 1 0
8 = -1 1 1 17 = 0 1 1 26 = 1 1 1
Also, wenn Sie das Gefühl abenteuerlich, können Sie:
- einfach die Anzahl der Permutationen t berechnen o Ausgang
- eine einfache Schleife, um durch den Bereich verwendet
- konvertiert jede Zahl in der Basis k * 2 + 1
- jede Ziffer Offset durch k Subtrahieren
Natürlich gibt es auch den einfacheren Ansatz angedeutet früher. Rufen Sie Counter(k, nest_level);
in dem folgenden Code auf. (Erklärung nach)
void WriteVector(const std::vector<int>& v)
{
for (const auto i : v)
std::cout << i << " ";
std::cout << std::endl;
}
bool VectorInc(const int k, std::vector<int>& v)
{
for (auto it = v.rbegin(); it != v.rend(); it++)
{
if ((*it) < k) {
(*it)++;
return true;
}
(*it) = -k;
}
return false;
}
void Counter(const int k, const int n)
{
std::vector<int> v(n, -k);
WriteVector(v);
while (VectorInc(k, v))
WriteVector(v);
}
Counter
initialisiert einen Vektor mit size == nest_level
und jedem Element mit -k
.
- In einer Schleife nennt es
VectorInc
Zugabe von 1 (oder Zählung) zu simulieren.
VectorInc
ist eine sehr einfache Funktion, die durch die Vektorelemente von rechts Schleifen so lange nach links, wie es einem „Übertrag“ ausführen muss.
- Es aktualisiert das aktuelle Element von 1.
- Zugabe Aber wenn das aktuelle Element es bei der maximalen
k
, sollte es wieder zu -k
und „Verschleppung“ +1 auf die Ziffer auf der linken Rollover.
- Wenn der Vektor schließlich
{k, k, k, ..., k}
erreicht, indem 1 rollt ein Überlauf jede Ziffer zurück zu -k
und VectorInc
kehrt falsche anzeigt, dass es war.
Pros: Einfach, keine Rekursion und wird mit so ziemlich allen Werten von k & n arbeiten.
Cons: Wird mit so ziemlich allen Werten von k & n arbeiten. Versuchen Sie einen scheinbar harmlosen Anruf wie Counter(10, 80)
und Sie werden lange warten, bis Ihr Programm die Atome im Universum zählt.
Haben Sie versucht, [diese Ente mit Gummi diskutieren] (https://en.wikipedia.org/wiki/Rubber_duck_debugging)? –