Que fait ce programme

Résolu/Fermé
Tbdc1119 - 30 sept. 2008 à 04:21
 tbdc1119 - 10 oct. 2008 à 08:57
Bonjour,
Je n'arrive pas a determiner ce que fait ce programme pourriez vous m'aider merci.

En fait g juste reussi a determiner que a la fin de l'execution les elements A[i..n-1] sont ranges dans l'ordre croissant.

F(A){ // A[0..n-1] stores a permutation of {1,2,...,n}
int i,j,k;
for ( i = n-1 ; i > 0 && (A[i-1] > A[i]) ; i--){
// empty statement
}
if ( i = 0 )
return 0;
for ( j = i+1 ; j < n && (A[i-1] < A[j]) ; j++){
// empty statement
}
swap( A[i-1], A[j-1] ); // swap values in the two entries
reverse ( A[i..n-1] ); // reverse entries in the subarray
return 1;
}

8 réponses

Bonjour,

Je pense que c'est un algorithme de tri d'un tableau composé de numériques.
Si j'ai compris : ton algo. s'apelle reverse() et il semble récursif puisque'il s'auto-appelle dans le corps du programme.

A préciser.
Bonne journée.
Jojo.
0
Non l'algo n'est pas du tout recursif. Il ne s'appelle pas reverse. le nom de l'algo c'est F(A).reverse ne fait que le miroir de A[i..(n-1)].
0
Rollin'babe !!
30 sept. 2008 à 10:11
Yep,

En effet - autant pour moi.
Bizarre - je vois pas ce qu'il fait en couchant ca sur des exemples.

Bon courage.
0
Rollin'babe !!
30 sept. 2008 à 10:32
Bouh,

Avec cette chtite correction cher jihelge :

if ( i == 0 )
return 0;

Ça sentait donc bien l'algo. de tri récursif vu comme ca.

Bonne journée.
0
jihelge Messages postés 71 Date d'inscription mardi 5 février 2008 Statut Membre Dernière intervention 4 octobre 2008 7
30 sept. 2008 à 11:23
Tu as raison Rollin'babe

J'ai fait un copié collé sans févifier ce détail qui produit un joli bug car la condition est toujours vrai et donc le return0 toujours exécuté !!!

Bonne journée
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Voila le code correspondant au programme en c++ et pour un tableau de longueur 6
Savez vouz ce que fait ce programme???

#include <iostream>
#include <math.h>
using namespace std;
int main () {

int temp;
int tab[6];
int i;
int j;
int k;
int tab2[6];
while (true) {
cin >> tab[0];
cin >> tab[1];
cin >> tab[2];
cin >> tab[3];
cin >> tab[4];
cin >> tab[5];
/*cout << tab[0] << endl;
cout << tab[1] << endl;
cout << tab[2] << endl;
cout << tab[3] << endl;
cout << tab[4] << endl;
cout << tab[5] << endl;*/



for ( i = 5 ; i > 0 && (tab[i-1] > tab[i]) ; i--){
// empty statement
}

if ( i == 0 ) {
cout << "0";
return 0;}

for ( j = i+1 ; j < 6 && (tab[i-1] < tab[j]) ; j++){
// empty statement
}

temp=tab[i-1];
tab[i-1]=tab[j-1];
tab[j-1]=temp;


for (k=0 ;k<i;k++) {
tab2[k]=tab[k]; }

for (k=i;k<6;k++) {
tab2[k]=tab[5-k+i];}

cout << tab2[0] << " " << tab2[1] << " "<< tab2[2] << " "<< tab2[3] << " "<< tab2[4] << " "<< tab2[5] << " " << endl;
cout << i-1 << j-1<<endl;


system("PAUSE");
}
return 1;

}
0
jihelge Messages postés 71 Date d'inscription mardi 5 février 2008 Statut Membre Dernière intervention 4 octobre 2008 7
2 oct. 2008 à 16:20
Bon celui là n'est pas récursif.
C'est sur,
j'ai revu toutes mes fiches de cours et je ne trouve pas celui-ci.
Il me fais penser à du bubble sort ou du tri par inversion mais il y a des trucs blizzards

Je ne comprends pas la copie de tab vers tab2 mais surtout la copie inversée de la fin du tableau en cours de tri.

Mais surtout je sortirai bien la saisie clavier de la boucle while (cin >> tab[] … )

#include <iostream>
#include <math.h>
using namespace std;
int main () {

int temp;
int tab[6];
int i;
int j;
int k;
int tab2[6];


while (true) { //boucle de tri


lecture de 6 nombres au clavier et rangement dans la table tab
j'aurais bien aimé
for( i = 0 ; i<=5; i++) cin>>tab[i];



cin >> tab[0];
cin >> tab[1];
cin >> tab[2];
cin >> tab[3];
cin >> tab[4];
cin >> tab[5];
/*cout << tab[0] << endl;

Impression de la table avec un nombre par ligne(la aussi une petite boucle

cout << tab[1] << endl;
cout << tab[2] << endl;
cout << tab[3] << endl;
cout << tab[4] << endl;
cout << tab[5] << endl;*/

parcours de la table à partir de la fin pour trouver une inversion

for ( i = 5 ; i > 0 && (tab[i-1] > tab[i]) ; i--){
// empty statement
}

il n'y a plus d'invertion on sort

if ( i == 0 ) {
cout << "0";
return 0;}

A partir de l'inversion recherche d'un sous tableau d'ordre inversé

for ( j = i+1 ; j < 6 && (tab[i-1] < tab[j]) ; j++){
// empty statement
}


permutation de tab[i-1] et tab[j-1] ( bornes du sous tableau)

temp=tab[i-1];
tab[i-1]=tab[j-1];
tab[j-1]=temp;


tansfert de tout le début du tableau Tab dans le tableau Tab2

for (k=0 ;k<i;k++) {
tab2[k]=tab[k]; }

remplissage de la fin de tab2 avec l'inversion de la fin de tab

for (k=i;k<6;k++) {
tab2[k]=tab[5-k+i];}

Impression de la table tab2 des nombres séparés par un espace

cout << tab2[0] << " " << tab2[1] << " "<< tab2[2] << " "<< tab2[3] << " "<< tab2[4] << " "<< tab2[5] << " " << endl;

Impression des bornes

cout << i-1 << j-1<<endl;


On fait une pause pour avoir le temps de lire

system("PAUSE");
}
return 1;

}
0
Ce probleme n'est pas resolu
0
en fait sa rend le mot d apres dans l ordre lexicographique
0
jihelge Messages postés 71 Date d'inscription mardi 5 février 2008 Statut Membre Dernière intervention 4 octobre 2008 7
30 sept. 2008 à 10:15
C'est zarbi ton truc :

La fonction est "no return" donc du type avoid nomalement
or la est est semble t il considérée comme int. puisque on fait deux return dans le corps (dont un en plein milieu !!!!)

A n'est pas déclaré il y a une faute à ce niveau on aurait dû avoir
unsigned int F( int* A ) {

A est donc un pointeur de integers on peut s'en servir comme un tableau d'integer l'usage A[i]est maintenant licite.
n n'est pas connu on l'obtient donc par effet de bord (héritage ascendant des variables globale au niveau d'appel N-1)
Il y a donc une faute de programmation pouvant entrainer un bug (surtout avec un nom pareil : n, une autre partie du code pouvant manipuler une variable n ailleurs).

On déclare tois int i,j,k; k ne sert pas dans le code un compilateur bien devrait nous donner un warning

La première boucle recherche à partir de l'avant dernière position une invertion des valeurs contenues dans A (règle de tri).
si il n'y a aucune invertion i ateind donc la valeur zéro (tout le tableau a été parcouru et est en ordre) sinon
L'autre boucle parcours à partir de là où on c'est arrêté et on remonte dans le tableau jusqu'à trouver la condition inverse. On détecte donc un morceau de tableau ordonné dans l'autre sens et deux cases A[i-1] et A[j-1] qui ne sont pas à la bonne place.

Donc on les swap en faisant appel à une fonction swap (a écrire) qui met a[i-1] en laisse puis met A[j-1] dans A[i-1] et enfin met la laisse dans A[j-1]
et c'est là le tour de passe passe
on appel une certaine fonction resverse sur le sous tableau à partir de i puisque jusque là c'était ordonné
et là c'est magique car en fait c'est le nom de la fonction et non F comme indiqué au début.
Quand à la déclaration et l'appel ce n'est pas du C mais une formulation symbolique de cet appel car l'appel récursif se fait sur le sous tableau.

la réelle sortie étant le return(0); qui fait la descente de pile d'appel, le return(1) n'est jamais exécuté et il est là pour faire peur aux chtits nenfants.

Le meilleur moyen pour t'en convaincre
essai ceci avec gcc sous Linux je te laisse le soin de finir le main avec l'appel principal avec un tableau désordonné.
n'oublie pas les include stdio etc...

avoid swap( int* A , int* B )
{
int laisse;
laisse = *A;
*A=*B;
*B=laisse;
}


//F(A)
unsigned int reverse( int* A, int i , int n)
{ // A[0..n-1] stores a permutation of {1,2,...,n}
int j,k;
//trace----------------------------------------------------------------------
printf("\nappel de reverse : %X – i=%i – n=%I :\n",A,I,n);
for(k=I;k<=n;k++);
{
printf("%i; ",A[k]);
}
printf("\n");
//fin trace-------------------------------------------------------------------

for ( i = n-1 ; i > 0 && (A[i-1] > A[i]) ; i--){
// empty statement
}
if ( i = 0 )
return 0;
for ( j = i+1 ; j < n && (A[i-1] < A[j]) ; j++){
// empty statement
}
swap( A[i-1], A[j-1] ); // swap values in the two entries
//reverse ( A[i..n-1] ); // reverse entries in the subarray
reverse( A, i , n-1);
printf("passage sur return(1)");//ne sera jamais exécuté
return 1;
}

main()
….
-1