Quel est le problème avec la première fonction d'échange?

J'écris un code pour générer la permutation d'éléments d'un tableau. J'ai écrit deux types différents de fonctions d'échange, l'un utilisant le stockage temporaire fonctionne bien tandis que l'autre qui n'utilise pas de stockage temporaire ne génère pas de sortie. Pourquoi cela se passe-t-il ??

Le code suivant fonctionne bien

#include
#include
using namespace std;
int tt=0;
void swap1 (int v[], int i, int j) {
    int t;

    t = v[i];
    v[i] = v[j];
    v[j] = t;
}   
void permute(int arr[],int n,int index)
{
     if(index==n)
                {
                for(int i=0;i< n ;j++)
         {
           swap1(arr,index,j);
           permute(arr,n,index+1); 
           swap1(arr,j,index);           
         }        
}
int main()
{
    int arr[]={'a','b','c','d'};
    permute(arr,4,0);
    cout<

Alors que le code suivant ne génère pas les permutations:

#include
#include
using namespace std;
int tt=0;
void swap(int v[],int i,int j)
{
     v[i]= v[i] + v[j];
     v[j]= v[i] - v[j];
     v[i]= v[i] - v[j];
}
void permute(int arr[],int n,int index)
{
     if(index==n)
                {
                for(int i=0;i< n ;j++)
         {
           swap(arr,index,j);
           permute(arr,n,index+1); 
           swap(arr,j,index);           
         }        
}
int main()
{
    int arr[]={'a','b','c','d'};
    permute(arr,4,0);
    cout<
0
Souvenez-vous aussi que std :: swap() existe et devrait être utilisé lorsque c'est possible, mais votre fonction swap() peut avoir un nom-conflit parce que vous utilisez espace de noms std;
ajouté l'auteur stefaanv, source

2 Réponses

S'il vous plait, pour l'amour de toutes les divinités auxquelles vous croyez (ou pas), n'utilisez pas de vilains hacks comme votre seconde fonction d'échange (ou le truc redoutable XOR-swap).

Ils sont totalement inutiles et généralement plus lents qu'une solution typique à variable temporaire. Ils se traduiront également par l'apparition de votre code sur des sites tels que Le Daily WTF , et des générations de programmeurs (qui ont pour maintenir une telle cruauté) maudira votre nom à travers les siècles à venir :-)

Et, dans tous les cas, ils ne fonctionneront pas si les deux éléments que vous «échangez» sont les mêmes parce que, dès que vous faites:

v[i]= v[i] + v[j];

i et j ont la même valeur, vous avez perdu les informations nécessaires pour que les autres étapes fonctionnent.

Vous pouvez le voir en action comme suit. Disons que vous avez deux variables distinctes , a = 20 et b = 30 . Travaillez à travers vos étapes:

a = a + b; //a <- (20 + 30) = 50, b still = 30.
b = a - b; //b <- (50 - 30) = 20, a still = 50.
a = a - b; //a <- (50 - 20) = 30, b still = 20.

Et ils sont échangés, bien que vous voudriez probablement regarder dans les cas de bord avec des schémas de débordement et d'encodage qui ne sont pas à deux (en C de toute façon, pas sûr que C ++ permette à ceux-ci de compléter).

Mais voyons ce qui se passe quand a et b sont la même variable (pas la même valeur mais le réel même variable, comme une référence). Donc, ils ont tous les deux la valeur de 20 et vous vous attendez à ce qu'ils soient tous les deux à 20 après un échange, mais jetons un coup d'œil:

a = a + b; //a <- (20 + 20) = 40, AND b = 40 as well.
b = a - b; //b <- (40 - 40) =  0, AND a =  0 as well.
a = a - b; //a <- ( 0 -  0) =  0, AND b =  0 as well.

Ce n'est pas vraiment le résultat attendu.

0
ajouté
@paxdiablo merci pour la suggestion ....
ajouté l'auteur manyu, source
+1 pour empêcher les gens d'utiliser des hacks laids qui n'ont aucun avantage puisque nous avons abandonné l'utilisation du langage d'assemblage sur les microprocesseurs 8 bits ...
ajouté l'auteur Axel, source
De plus, en fonction du contenu du tableau, un dépassement/sous-dépassement peut se produire pendant le calcul.
ajouté l'auteur swegi, source
void swap(int v[],int i,int j)
{
     v[i]= v[i] + v[j];
     v[j]= v[i] - v[j];
     v[i]= v[i] - v[j];
}

ne fonctionne pas quand i == j (il met alors v [i] à 0), quelque chose qui se passe avec votre boucle

for (int j = index; j < n; ++j) {
    swap(arr, index, j);
0
ajouté
Je n'ai pas cliqué sur mon esprit ... merci beaucoup, vous m'avez sauvé beaucoup de temps. :)
ajouté l'auteur manyu, source