2016-05-19 6 views
1

Ich mag würde, eine Funktion schreiben folgendes zu tun, da zwei Argumente der Funktion int K und int nest_level alle möglichen Punkte erzeugen, die nest_level verschachtelte Schleifen von der Erstellung führen, dass jede Schlaufe aus -K reicht zu K. Zum Beispiel, wenn k = 5 und nest_level = 3 druckt die Funktion, die die Sequenzen von Zahlen, die aus dem folgenden führen:Generieren alle Werte von N für Schleifen verschachtelt

for(int i = -k; i <= k; ++i) 
    for(int j = -k; j <= k; ++j) 
     for(int m = -k; m <= k; ++m) 
      print(i, j, k) 

Dies sollte für Arbeit jedes K und nest_level

Aus meiner Forschung, verstehe ich diese eine rekursive Lösung sein sollte aber ich habe Schwierigkeiten, es speziell in C++ zu implementieren.

+3

Haben Sie versucht, [diese Ente mit Gummi diskutieren] (https://en.wikipedia.org/wiki/Rubber_duck_debugging)? –

Antwort

1

Verwenden Sie eine std::vector. Übergeben Sie es als Referenz. In einer Schleife von i von -k bis k:

  • Push i hinein.

  • Wenn die Länge des Vektors der Verschachtelung entspricht, drucken.

  • Andernfalls recurse und übergibt den Vektor als Referenz.

  • Jetzt das letzte Element vom Ende des Vektors knallen und die Schleife fortsetzen.

0

So etwas wie dies, benötigen Sie einen Container-Nummer zu speichern

#include "iostream" 
#include "vector" 

void print(const std::vector<int>& v) { 
    for (auto i : v) { 
     std::cout << i << ' '; 
    } 
    std::cout << std::endl; 
} 

void genImpl(int K, int level, std::vector<int>& cache) { 
    if (level == 1) { 
     for (int i = -K; i <= K; ++i) { 
      cache.push_back(i); 
      print(cache); 
      cache.pop_back(); 
     } 
    } else { 
     for (int i = -K; i <= K; ++i) { 
      cache.push_back(i); 
      genImpl(K, level - 1, cache); 
      cache.pop_back(); 
     } 
    } 
} 

void gen(int K, int level) { 
    std::vector<int> cache; 
    genImpl(K, level, cache); 
} 

int main() { 
    gen(2, 3); 
    return 0; 
} 
0
because both parameters are int type, so ,first you should get their abs value. 

//pseud0-code 

{ 
    k = abs(k); 
    nest_level = abs(nest_level); 
    while(nest_level--){ 
    for(int i = -k; i < k; i++){ 
     printf("%d,%d", nest_level, i); 
    } 
    printf("\r\n"); 
    } 
} 
1

Eine andere Möglichkeit, um dieses Problem zu denken, dass Sie mit einer Reihe arbeiten, wobei jede Ziffer von -K reicht zu K. Sie können (-K) (- K) (- K) ... (- K) (- K) (- K) bis zu KKK ... KKK erhöhen und die Zwischenergebnisse ausdrucken.

#include <iostream> 
#include <vector> 

bool increment(int K, std::vector<int> & vals) { 
    int position = vals.size()-1; 
    while (vals[position] == K) { 
     vals[position] = -K; 
     --position; 
     if (position == -1) { 
      return false; 
     } 
    } 
    ++vals[position]; 
    return true; 
} 

void count(int K, int nest_level) { 
    std::vector<int> vals; 
    for (int n=0; n<nest_level; ++n) { 
     vals.push_back(-K); 
    } 

    do { 
     for (auto v : vals) { 
      std::cout << v << " "; 
     } 
     std::cout << "\n"; 
    } while (increment(K, vals)); 
} 

int main() 
{ 
    count(1, 2); 
    return 0; 
} 

Ich bin nicht sicher, welcher Weg besser ist, aber ich dachte, es war eine saubere Parallele.

0

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.