Permutacja w C++ dla N początkowych naturalnych

0

Witam, mam do zrobienia program który wypisuje wszystkie permutacje zadanych n liczb z zakresu 1-9 (początkowych naturalnych). Niestety przy wprowadzeniu tablicy dynamicznej mam problem... Za każdym razem wyświetla mi tylko 1 i program się kończy... czy ktoś miałby może jakieś wskazówki co robię źle? :)

// permutacja.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>

void permutacja(int t[], int max);
void wypisz(int t[], int max);

long silnia(int n) {
int i;
long tmp=1;

for(i=2;i<=n;i++)
  tmp*=i;
return tmp;
}


int main(void)
{
	int *t;
	int n=0;
	for(n=0;n==0;)
	{
	fflush(stdin);
	printf("Podaj n:");
	scanf("%i",&n);
	if (n==0)
	{
		printf("Blad, podaj wartosc z przedzialu 1-9");
		
		
	}
	}


t = new int[n];

	for(int x=0;x<=n;x++)
	{
		t[x]=x+1;
	}

    int MAX=sizeof(t)/sizeof(t[0]);
    int i, j;

    wypisz(t, MAX);
    for (i = 0; i < silnia(MAX) -1 ; i++) { 
        permutacja(t, MAX);
        wypisz(t, MAX);
    }

    return 0;

}

/* permutacja: generuje nastepnik permutacyjny dla zadanego szeregu
liczb
*/
void permutacja(int t[], int max)
{
    int i, j, k;

    if (max < 2)
        return;

    /* wyznaczanie pierwszego od prawej elementu
     * mniejszego niz jego sasiad z prawej strony
     */
    i = max - 1;
    while ((i > 0) && (t[i - 1] >= t[i]))
        i--;

    /* wyznaczanie elementu wiekszego od znalezionego */
    if (i > 0) {
        j = max;
        while ((j > 0) &&(t[j - 1] <= t[i - 1]))
            j--;
    }

    /* zamiana miejscami dwoch znalezionych wyzej elementow */
    if ((i > 0) && (j > 0)) {
        k = t[i - 1];
        t[i - 1] = t[j - 1];
        t[j - 1] = k;
    }

    /* odbicie lustrzane szeregu elementow od indeksu i+1 do konca
tablicy
*/
    for (i++, j = max; i < j; i++, j--) {
        k = t[i - 1];
        t[i - 1] = t[j - 1];
        t[j - 1] = k;
    }

}

/* wypisz: wypisuje zawartosc tablicy
*/
void wypisz(int t[], int max)
{
    int i;

    for (i = 0; i < max; i++)
        printf("%d%c", t[i], (i < max - 1) ? ' ' : '\n');
}

 

Dziękuję :)

1

W C++ w roli tablic dynamicznych w 95 % przypadków lepiej jest używać vectora. Sizeof nie zwraca Ci wielkości tablicy, ponieważ to nie jest tablica, tylko wskaźnik do miejsca w pamięci. Robisz pewnie to na kompilatorze 32 bitowym, więc zastępuje Ci to wywołanie wartością 4 (to nie jest funkcja, tylko operator, zwraca on wielkość typu, zwykle podczas kompilacji (poza VLA, ale to nie jest standardowy C++). Działa to w przypadku tablic statycznych, ponieważ w czasie kompilacji ich rozmiar jest znany i na stosie podczas wykonywania danej funkcji znajduje się cała tablica, a nie tylko wskaźnik.

0

Dziękuję bardzo za błyskawiczną odpowiedź. Niestety można powiedzieć że znam tylko podstawy C++... Korzystam z MS Visual Studio 2010, 32 bitowego. Jest możliwość przerobienia mojego kodu na taki spełniający swoją rolę? Głównie chodzi o tą tablicę... mam 9 różnych możliwości ale nie chcę dla każdego przypadku robić osobnego warunku...

Wektory mnie trochę "przerażają" gdy wskaźników jeszcze do końca nie pojąłem :(

0

Jeżeli tworzysz tablicę przez new, to musisz przechowywać jej wielkość osobno. Akurat tak się składa, że masz ją w zmiennej n. Jeszcze jest jeden błąd, jeżeli indeksujesz coś, co jest indeksowane od 0, to warunek końcowy powinien wyglądać indeks < rozmiar, a nie indeks <= rozmiar, ta konwencja jest też przestrzegana przy korzystaniu z iteratorów do kontenerów STLowskich (choć iterator jest metaforą wskaźnika i porównuje się begin != end, a nie begin < end, ze względu na to, że nie wszystkie iteratory muszą mieć jawnego uporządkowania).

0

Wielkie dzięki za pomoc :)

zmieniłem

int MAX=sizeof(t)/sizeof(t[0]); 

na

int MAX=n; 

i działa bez zarzutów :)

oczywiście też zmieniłem <= na samo <

Jeszcze raz bardzo Ci dziękuję :)

0

Aleś nakombinowałeś, wszystko da się zrobić o wiele prościej:

#include <stdio.h>
#include <string.h>

void swap(char *a,char *b)
  {
   char c=*a; *a=*b; *b=c;
  }

int permutacja(char t[])
  {
   int i,j,n;
   
   n=strlen(t);
   for(i=n-2;(i>=0)&&(t[i]>=t[i+1]);--i) {}
   if(i<0) return 0;
   for(j=n-1;(j>i)&&(t[j]<=t[i]);--j) {}
   swap(t+i,t+j);
   for(++i,j=n-1;i<j;++i,--j) swap(t+i,t+j);
   return 1;
  }

int krok(char t[])
  {
   printf("%s\n",t);
   return permutacja(t);
  }

int main(void)
  {
   char t[10]={0}; // przydzielanie dynamiczne na 9 elementów się nie oplaca
   int i,n=0;

   for(;;)
     {
      printf("Podaj n (0-koniec): ");
      if((scanf("%i",&n)==1)&&(0<=n)&&(n<=9))
        {
         if(!n) break;
         for(i=0;i<n;++i) t[i]='1'+i;
         while(krok(t)) {}
         printf("\n");
        }
      else
        {
         fflush(stdin);
         printf("Blad, podaj wartosc z przedzialu 0-9\n\n");
        }
     }
   return 0;
  }
0

W C++ od tego jest std::next_permutation z <algorithm>.

http://www.cplusplus.com/reference/algorithm/next_permutation/

1 użytkowników online, w tym zalogowanych: 0, gości: 1