Problem mit einer Rekursionsfunktion

Hallo Leute,

ich verzweifele heute. Ich habe eine Rekursionsfunktion in C++, die echt gut funktioniert. Ich will Sie in VB übersetzen und das geht leider schief. Ich poste man sowohll C++ als auch mien gescheiterter VB-Versuch, um zu hoffen, dass mir jemand helfen kann.

Danke

Kurt

---------- C++ --------------

void kombi(int n, int kk)
{

//Vervollständigung aller Komb. ohne N
if (n > kk)
kombi(n - 1, kk);

// kombinationen mit N
if (n >= kk)
{
kk=kk-1;

//Zwischensppeichern von N
A[kk] = n;
if (kk > 0)

kombi(n - 1, kk);
else
{
// Ausgabe
for (int j = 0; j kk Then kombi n - 1, kk

If n >= kk Then
A(kk) = n

If kk > 0 Then
kk = kk - 1
kombi n - 1, k
Else
For j = 0 To temp - 1
E(k, j) = A(k)
Next j

k = k + 1
End If

End If
End Sub

Hallo Kurt,

Private Sub kombi(n, k)

If n > kk Then kombi n - 1, kk

ich verstehe eigentlich weder Dein Problem, noch was Du vor hast, dafür kenne ich VB ein wenig. Vermutlich werde ich bei der Lösung mehr lernen als Du. :wink:

Was soll der Code bewirken? Die Prozedur ruft sich selbst auf? Führt das nicht zu einer Endlosschleife? Ich würde an der Stelle erwarten, daß sich das programm aufhängt, weil immer mehr Teilprozesse gestartet werden.

Was passiert wirklich und was soll das Programm bewirken?

Wozu soll das gut sein, daß sich die Prozedur selbst aufruft?

Gruß, Rainer

Das Programm soll alle Kombiantionen von k aus n Elementen in einem zweidim. Array schreiben. z.B. 4 über 2

1 2
1 3
1 4
2 3
2 4
3 4

Ich hoffe, es hilft. Etwas stimmt bei der If-Abfrage nicht. Wie gesagt in C klappt es.

Hi,

Das Programm soll alle Kombiantionen von k aus n Elementen in
einem zweidim. Array schreiben. z.B. 4 über 2

OK, der mathematische Hintergrund fehlt mir. Wie das ergebnis aussehen soll, weiß ich aber,. :wink:

1 2
1 3
1 4
2 3
2 4
3 4

Ich hoffe, es hilft.

Ja.

Etwas stimmt bei der If-Abfrage nicht.

Nein. :wink:

Wie gesagt in C klappt es.

Schade, den C-Code kann ich nicht lesen. ;-(

Was mir an Probelmem für VB aufgefallen ist. …

For j = 0 To temp - 1

Die Schleife tut nichts, weil temp leer ist und nirgends versorgt wird.

Im C-Code steht:

E[k][j] = A[j];

in VB

E(k, j) = A( k )

das scheint ein Tippfehler zu sein.

C

kombi(n - 1, kk);

VB

kombi n - 1, k

ebenfalls.

c
void kombi(int n, int kk)
VB
Private Sub kombi(n, k )

ebenfalls.
Im VB-Code ist kk nie >0.

Hoffentlich hilft’s. :wink:

Gruß, Rainer

Hi!

ich verzweifele heute. Ich habe eine Rekursionsfunktion in
C++, die echt gut funktioniert. Ich will Sie in VB übersetzen
und das geht leider schief. Ich poste man sowohll C++ als auch
mien gescheiterter VB-Versuch, um zu hoffen, dass mir jemand
helfen kann.

Schauen wir uns mal den VB-Code an:

-------- VB-Versuch------------------------

Private Sub kombi(n, k)

Variablen n und k werden übergeben.
Das sind damit schon mal lokale Variablen, die bei einem rekursiven Aufruf erneut als lokale Variablen angelegt werden.

If n > kk Then kombi n - 1, kk

Wieso jetzt kk? Woher kommt kk? Was hat kk als Inhalt?

If n >= kk Then
A(kk) = n

Ein Array, das nicht redimensioniert wurde?
Ist das Array außerhalb der SUB dimensioniert worden? Wenn ja, in welcher Größe? Das Array ist doch vom Übergabeparameter abhängig?

If kk > 0 Then
kk = kk - 1
kombi n - 1, k

Der Wert kk wird verändert, aber die SUB mit dem Wert k aufgerufen. Kann so nicht funktionieren.

Else
For j = 0 To temp - 1

Was ist jetzt temp? Woher kommt temp? Welchen Wert hat temp?
Wenn temp nicht per Global oder Public deklariert wurde, steht temp auf 0. Davon ziehst du 1 ab. Macht -1. Startwert der For-Schleife ist 0. Startwert größer als Ende-Wert, ergo läuft die For-Schleife nicht an.

E(k, j) = A(k)

Erneut: Wie ist E(k,j) dimensioniert?

Next j

k = k + 1
End If

End If
End Sub

Nach meinem Verständnis kann dieser VB-Code niemals laufen bzw. gelaufen sein. Sende doch mal den richtigen VB-Code.

Grüße
Heinrich

Sorry Leute,

Sowohl die beiden Arrays, als auch k und temp sind globale Variablen. Das Problem selbst habe ich gelöst, indem ich über VB eine C-Dll aufrufe. Trotzdem - ausser reiner neugier - will ich wissen, warum es nicht in VB klappt.

Gruß Kurt

Hi Kurt,
kommentiere doch mal den C-Code. Die offensichtlichen Tippfehler habe ich ja schon geschrieben. das Probelm ist ‚Temp‘. Wo bekommt das den Inhalt her? Da scheint das Problem, der Unterschied von C und VB zu liegen, denn der Teil macht unter VB keinen Sinn.

Gruß, Rainer

Private Sub kombi(n, k)

Ganz einfach, in VB sind alle nicht anders bezeichneten Parameter Variablenparameter, also solltest du mal Private Sub kombi(byval n, byval k) ausprobieren…

Ralph

Hallo Rainer,

ich habe den Code in eine C++ Klasse umgeschrieben. Ich poste mal die ganze Klasse.

Gruß Kurt

----- Code-----
#include

typedef unsigned int uint; //Typendefinition

// Hilfsfunktionen im alten C Stil
double logfak(uint n); // Fakultät
uint binomial(uint n,uint r); //Binomialkoeffizient

/* Hauptklasse

Algorithmus zur Aufzählung alle Kombinationen von k aus n Elementen [C(n,k)]

*/
class kombi {

public:

kombi(uint,uint); // Constructer
~kombi(); // Destructor

uint n; //n
uint k; //k
uint komb; // Anzahl der Kombinationen

uint* E; // Zeiger auf Ausgabe-Array

private:
uint z; // Zähler
uint temp; // temporäre Variable
uint* A; // * zeiger auf Hilfs-Array
void algo(uint,uint); //Hauptroutine
};

kombi::kombi(uint n, uint k)
{
uint N_;
uint K_;
z=0;
N_ = n; // N
K_ = k; // n
temp = K_; // temporäre Datei wird mit k gesetzt
A = new uint [N_] ; // Arraygröße

komb = binomial(N_, K_); //maximale Kombinationen

// Erstellung des dynamischen Ausgabearrays

E = new uint [komb*temp]; // Arraygröße

algo(N_, temp); // Start
delete [] A; // Speicher freigeben
delete [] E; // Speicher freigeben

}

kombi::~kombi()
{

}

void kombi::algo(uint n, uint kk)
{

//Vervollständigung aller Komb. ohne N
if (n > kk)
algo(n - 1, kk);

// kombinationen mit N
if (n >= kk–)
{
A[kk] = n;

if (kk > 0)

//Zwischensppeichern von N
algo(n - 1, kk);
else
{
// Ausgabe
for (uint j = 0; j r)
{
bin = logfak(n) - logfak® - logfak(n - r);
}
bin=exp(bin);
return (uint)bin;
}

double logfak(uint n)
{
double logfak = 0;
for (int unsigned i = 0; i