1
votes

Additionner les éléments positifs d'un tableau en utilisant la récursivité

J'apprends la récursivité et j'essaie de calculer la somme des éléments positifs d'un tableau mais je ne sais pas comment le faire. Quelqu'un peut-il m'aider?

#include <iostream>
using namespace std;
    
int sum (int arr[],int n)
{
    if(n==-1)
    return  0;
    /*else if(arr[n]<0)
    return arr[n]+sum(arr,n+1) ;*/
    else
    return arr[n-1]+sum(arr , n-1);
        
}
    
int main()
{
    int  n , arr[n] ;
    cout<<"give the value of  n : " ; cin>>n;
    cout<<"give the values of the array ";
    for(int i=0;i<n;i++)
    cin>>arr[i];
    cout<<"the value of positive elements is  : " << sum(arr,n);
    return 0;
}


4 commentaires

Veuillez préciser quel est exactement votre problème, lisez Comment demander plus d'informations. En tant que nouvel utilisateur, faites également le tour . BTW: Cela peut être utile si vous codez en dur les valeurs au lieu de les saisir manuellement, cela permet des tests plus faciles avec une source d'erreur en moins.


Dans la première ligne de main, quelle est la valeur de n? quelle est la taille de arr?


Ainsi que les autres erreurs, en sum si n est 0 , alors vous allez dans la clause d' autre et finissent par accéder arr[-1] qui est peu probable ce que vous voulez.


Même si vous utilisez l'extension du compilateur pour activer les tableaux de longueur variable en C ++, déclarez int arr[n]; avant d'avoir initialisé n avec quoi que ce soit ne fonctionnera pas. Il doit allouer de la mémoire pour arr lorsqu'il est déclaré, et non rétroactivement après avoir attribué une valeur à n .


3 Réponses :


0
votes

Votre fonction récursive doit renvoyer l'une des trois valeurs suivantes:

  1. Si nous avons atteint la fin du tableau, renvoyez zéro
  2. Sinon, si l'élément du tableau 'courant' est négatif ou nul, renvoie la récursivité 'suivante'
  3. Sinon, si l'élément «courant» est positif, renvoie la somme de cela et de la récursivité suivante.

À chaque appel récursif, nous devons: (a) Incrémenter l'index de l'élément «courant»; et (b) réduire le nombre d'éléments laissés dans le tableau. Pour (a), nous pouvons utiliser le fait qu'un tableau passé en tant que paramètre de fonction se désintègre en un pointeur vers son premier élément , nous pouvons donc simplement en ajouter un à ce pointeur pour l'appel récursif:

int sum(int arr[], int n)
{
    if (n <= 0) return 0; // Reached the end of the array: return zero
    if (*arr <= 0) return sum(arr + 1, n - 1); // Non-positive number: skip it
    return sum(arr + 1, n - 1) + *arr;  // Add this number to the recursion result!
}

N'hésitez pas à demander des précisions et / ou explications supplémentaires.


EDIT: De plus, si vous insistez pour utiliser des tableaux de longueur variable (VLA - pas le C ++ standard), vous devez déclarer int arr[n] après avoir lu la valeur de n donnée par l'utilisateur. Mais je recommanderais d'utiliser une taille fixe (maximale), comme: int n, arr[100]; .


6 commentaires

Vous pouvez enregistrer un autre.


@Surt Indeed (voir modifier). J'étais coincé entre deux styles: utiliser else pour le deuxième et le troisième cas (pour plus de clarté) ou ne pas l'utiliser du tout. J'ai maintenant fait une non-utilisation cohérente de l' else .


salut ! votre réponse a également fonctionné, mais dans certains cas, comme lorsque j'ai choisi 2 comme longueur de tableau ne fonctionne pas, savez-vous quelque chose à propos de cette erreur


@WalidWalid Je ne peux pas reproduire votre erreur avec une longueur de tableau de 2 (voire 1). Avez-vous apporté les modifications suggérées dans le dernier paragraphe?


mais si nous avons fixé la taille pourquoi nous ajoutons n sur les arguments de la fonction! Remarque: si je fixe la taille et la change après toujours le même problème


@WalidWalid Lorsque vous passez un tableau à une fonction, cette fonction ne peut pas déterminer par elle-même la taille du tableau ... à moins que vous ne le lui disiez! C'est pourquoi nous passons le paramètre n , et pourquoi nous le diminuons de un pour chaque appel récursif (le tableau «restant» est plus petit pour chacun de ces appels).



0
votes

Quelques suggestions:

  1. en C ++ (spécialement à partir de C ++ 11), évitez, si possible, les anciens tableaux de style C; utilisez std::vector , std::deque , std::array (à partir de C ++ 11);

  2. Lorsque cela est possible, écrivez du code générique à l'aide de modèles; dans ce cas, évitez une fonction sum() qui ne fonctionne qu'avec des tableaux de style C, mais écrivez une fonction modèle qui peut également fonctionner avec std::vector , etc.

  3. Lorsque vous gérez les tailles, utilisez des entiers non signés ( std::size_t , par exemple), et non des entiers signés; ceci pour être cohérent avec la bibliothèque C ++ standard et éviter beaucoup d'incohérences signées / non signées.

Étant donné que vous apprenez la récursivité, je propose la fonction sum() suivante

#include <vector>
#include <iostream>

template <typename T>
int sum (T const & arr, std::size_t n)
 {
   return   ( arr[n] > 0 ? arr[n]        : 0)
          + (      n > 0 ? sum(arr, n-1) : 0);
 }

int main()
 {
   std::size_t      dim;
   std::vector<int> vec;

   std::cout << "give the value of  n : " ; std::cin >> dim;
   std::cout << "give the values of the array ";

   vec.resize(dim);

   for ( auto & val : vec )
      std::cin >> val;

  
   std::cout << "the value of positive elements is  : " 
      << (dim > 0u ? sum(vec, dim-1u) : 0) << std::endl;
 }

Observez la première rangée, où

+ (      n > 0 ? sum(arr, n-1) : 0);

arr[n] est ajouté à la somme ssi (si et seulement si) est supérieur à zéro (sinon est ajouté zéro)

Observez également la deuxième rangée, où

( arr[n] > 0 ? arr[n]        : 0)

la récursion continue ( sum(arr, n-1) est ajoutée) ssi n est supérieur à zéro.

Voici un exemple de compilation complet qui utilise std::vector .

template <typename T>
int sum (T const & arr, std::size_t n)
 {
   return   ( arr[n] > 0 ? arr[n]        : 0)
          + (      n > 0 ? sum(arr, n-1) : 0);
 }


3 commentaires

Je suis nouveau dans cette langue mais merci beaucoup pour vos conseils !!


@AdrianMole - D'Oh! Erreur horrible. Corrigée. Merci.


@WalidWalid - Il y avait une horrible erreur dans mon code (voir le commentaire d'Adrian Mole); corrigée.



-1
votes

... apprendre la récursion et essayer de calculer la somme des éléments positifs d'un tableau ...

Considérez ce qu'il faut faire s'il n'y avait qu'un seul élément dans le tableau, puis codez pour cela.
return (arr[0] > 0) ? arr[0] : 0;

Sinon, divisez le problème en un sous-problème plus petit.

D'autres ont répondu comment , mais l'utilisation de la récursivité est une manière itérative - ne décrémentant que la taille du tableau. La profondeur de récursivité pourrait être O(n) .

Je recommande de diviser par deux la taille du problème.
Cette alternative utilise une profondeur beaucoup plus petite: O(log n) .

int sum (const int arr[], int n) {
  if (n <= 1) {
    return (n > 0 && arr[0] > 0) ? arr[0] : 0;
  }
  int left_size = n/2;
  return sum(arr, left_size) + sum(arr + left_size, n - left_size);
}

0 commentaires