web-dev-qa-db-fra.com

Inverser un tableau sans utiliser l'itération

Une question m’a été posée aujourd’hui et je ne crois pas que ce soit possible, mais je peux me tromper ou j’y réfléchis trop. Comment pouvez-vous inverser un tableau sans utiliser l'itération en C?

Je pense que c'est impossible car le tableau peut avoir n'importe quelle taille et qu'aucun programme C ne peut être exprimé avec ce type de support à l'esprit sans utiliser une forme quelconque d'itération.

36
Michael J. Gray

Comme les gens l'ont dit dans les commentaires, cela dépend de la définition de l'itération.

Cas 1. Itération en tant que style de programmation, différent de la récursivité

Si on prend la récursion (simplement) comme une alternative itération, alors la solution récursive présentée par Kalai est la bonne réponse.

Cas 2. Itération en tant que temps linéaire inférieur

Si l'on prend l'itération comme "examinant chaque élément", la question devient alors de savoir si l'inversion d'un tableau nécessite un temps linéaire ou peut être effectuée dans un temps sous-linéaire.

Pour montrer qu'il n'existe pas d'algorithme sous-linéaire pour l'inversion de tableau, considérons un tableau avec n éléments. Supposons qu'un algorithme A existe pour l'inversion et qu'il ne soit pas nécessaire de lire chaque élément. Ensuite, il existe un élément a[i] pour une variable i dans 0..n-1 que l'algorithme ne lit jamais, tout en pouvant toujours inverser correctement le tableau. (EDIT: Nous devons exclure l'élément central d'un tableau de longueur impaire - voir les commentaires ci-dessous de cette plage - voir les commentaires ci-dessous - mais cela n'a pas d'incidence sur le fait que l'algorithme soit linéaire ou sous-linéaire dans le cas asymptotique.)

Comme l'algorithme ne lit jamais l'élément a[i], nous pouvons changer sa valeur. Disons que nous faisons cela. Ensuite, l’algorithme, n'ayant jamais lu cette valeur du tout, produira la même réponse pour l’inversion qu’il l’avait fait avant de changer sa valeur. Mais cette réponse ne sera pas correcte pour la nouvelle valeur de a[i]. Par conséquent, un algorithme d'inversion correct qui ne lit pas au moins tous les éléments du tableau en entrée (sauf un) n'existe pas. Par conséquent, l'inversion de tableau a une limite inférieure de O(n) et donc nécessite itération (selon la définition de travail de ce scénario).

(Notez que cette preuve est uniquement destinée à l'inversion de tableau et ne s'étend pas aux algorithmes qui ont réellement des implémentations sublinéaires, comme la recherche binaire et la recherche d'élément.)

Cas 3. Itération en tant que construction en boucle

Si l'itération est considérée comme "en boucle jusqu'à ce qu'une condition soit remplie", cela se traduit par un code machine à sauts conditionnels, connu pour exiger une optimisation sérieuse du compilateur (en tirant parti de la prédiction de branche, etc.). Dans ce cas, façon de faire quelque chose "sans itération" peut avoir à l'esprit boucle déroulante} _ (en code en ligne droite). Dans ce cas, vous pouvez en principe écrire du code C en ligne droite (sans boucle). Mais cette technique n’est pas générale; cela ne fonctionne que si vous connaissez à l'avance la taille du tableau. (Désolé d'ajouter ce cas plus ou moins désinvolte à la réponse, mais je l'ai fait pour être complet et parce que j'ai entendu le terme "itération" utilisé de cette manière, et le déroulement de la boucle est une optimisation importante du compilateur.)

23
Ray Toal

Utilisez la fonction récursive.

void reverse(int a[],int start,int end)
{
     int temp;
     temp = a[start];
     a[start] = a[end];
     a[end] = temp;


    if(start==end ||start==end-1)
       return;
    reverse(a, start+1, end-1);
}

Appelez simplement la méthode ci-dessus en tant que reverse (array, 0, lengthofarray-1)

14
Kalai Selvan Ravi

Implémentez une fonction récursive pour inverser un tableau trié. C'est-à-dire, étant donné le tableau [1, 2, 3, 4, 5], votre procédure Devrait renvoyer [5, 4, 3, 2, 1].

1
Ntsika

Voici une solution intéressante utilisant la récursivité dans une fonction javascript. Il ne nécessite aucun paramètre autre que le tableau lui-même.

/* Use recursion to reverse an array */
function reverse(a){
    if(a.length==undefined || a.length<2){
        return a;
    }
    b=[];
    b.Push(reverse(copyChop(a)));
    b.Push(a[0]);
    return b;
    /* Return a copy of an array minus the first element */
    function copyChop(a){ 
        b=a.slice(1); 
        return b;
    }
}

Appelez ça comme suit;

reverse([1,2,3,4]);

Notez que si vous n'utilisez pas la fonction imbriquée copyChop pour découper le tableau, vous obtenez un tableau comme premier élément de votre résultat final. Pas tout à fait sûr pourquoi cela devrait être si

0
Phil C
   #include<stdio.h>


   void rev(int *a,int i,int n)
  {

if(i<n/2)
{
    int temp = a[i];
    a[i]=a[n-i-1];
    a[n-i-1]=temp;
    rev(a,++i,n);
 }
}
int main()
    {
    int array[] = {3,2,4,5,6,7,8};
   int len = (sizeof(array)/sizeof(int));
   rev(array,0,len);    
   for(int i=0;i<len;i++)
   {
    printf("\n array[%d]->%d",i,array[i]);
  }
}
0
Monis Majeed