Ainsi, dans ma tentative de commencer à apprendre C # Un défi, j'ai rencontré est de créer une fonction récursive qui calculera la somme d'une liste. Je me demande s'il est possible de faire cela en utilisant une liste comme seul argument de la fonction? Ou devrais-je appliquer une taille d'index aussi pour travailler via la liste? J'espérais avoir attribué le total au premier index de la liste avant de supprimer le premier index de la liste que lorsqu'elle est passée dans l'instance suivante de la fonction, l'index de chaque élément de la liste se déplacerait une, ce qui me permettrait d'obtenir chaque valeur dans la liste et de les totaliser. Cependant, l'utilisation de la fonction ne renvoie jamais le dernier élément de la liste des entiers que j'entre. P> mon processus de pensée provenait de tableaux et l'idée de la méthode de décalage sur un tableau dans JS, en supprimant le premier élément et Amener tout le truc. P> suis-je en train de tenter quelque chose de stupide ici? Y a-t-il une autre méthode similaire que je devrais utiliser ou serais-je mieux à partir de simplement inclure une taille de liste comme un autre paramètre? P> Merci pour votre temps P> P>
3 Réponses :
Ce sont quelques façons d'obtenir la somme des entiers dans une liste.
Vous n'avez pas besoin d'une méthode récursive, il passe plus de ressources système quand ce n'est pas nécessaire. P>
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
int sum1 = numbers.Sum();
int sum2 = GetSum2(numbers);
int sum3 = GetSum3(numbers);
int sum4 = GetSum4(numbers);
}
private static int GetSum2(List<int> numbers)
{
int total = 0;
foreach (int number in numbers)
{
total += number;
}
return total;
}
private static int GetSum3(List<int> numbers)
{
int total = 0;
for (int i = 0; i < numbers.Count; i++)
{
total += numbers[i];
}
return total;
}
private static int GetSum4(List<int> numbers)
{
int total = 0;
numbers.ForEach((number) =>
{
total += number;
});
return total;
}
}
Ainsi, dans ma tentative de commencer à apprendre C # Un défi, j'ai rencontré est de créer une fonction récursive qui calculera la somme d'une liste. Je me demande s'il est possible de faire cela en utilisant une liste comme seul argument de la fonction? Ou devrais-je appliquer une taille d'index aussi pour travailler via la liste? P> blockQuote>
C'est un excellent exercice pour un débutant. Cependant, vous ne le feriez jamais avec une liste
code> dans un programme réaliste. Tout d'abord, parce que vous appeliez simplement .sum () code> dessus. Mais c'est un flexible; Quelqu'un a dû écriresomme code>, et cette personne pourrait être toi. P>La raison pour laquelle vous ne feriez jamais que cette liste est de la liste
code> n'est pas une structure de données récursif. Comme vous le note, chaque fois que vous recurrez, il doit y avoir quelque chose de différent fort>. S'il n'y a pas quelque chose de différent, vous avez une récursion sans bornes! p> Cela signifie que vous devez modifier l'un des arguments, que ce soit en la mutateur, s'il s'agit d'un type de référence ou de transmettre un argument différent.
ni n'est correct dans ce cas où l'argument est une liste forte>. p> Pour une liste, vous ne voulez jamais muter la liste, en supprimant les articles, par exemple. Vous ne possédez pas cette liste forte>. L'appelant em> possède la liste et il est impoli de la muter sur eux. Lorsque j'appelle votre méthode pour résumer une liste, je ne veux pas que la liste soit vidée; Je voudrais peut-être l'utiliser pour autre chose. p>
Et pour une liste, vous ne voulez jamais transmettre une liste différente dans une récursion car construire la nouvelle liste de l'ancienne liste est très coûteux em>. p>.
(Il y a aussi la question de la récursion profonde; vraisemblablement, nous souhaitons résumer des listes de plus de mille chiffres, mais cela mangera tout l'espace de pile si vous allez avec une solution récursive; c # n'est pas une queue garantie -Récours similaire comme F # est. Toutefois, à des fins d'apprentissage, ignorons ce problème et supposons que nous ne traitons que de petites listes.) p>
Comme les deux techniques permettant d'éviter les récursions sans bornes sont inapplicables, vous ne devez pas écrire des algorithmes récursifs sur
listcode> (ou, comme vous le souhaitez, vous devez transmettre un paramètre auxiliaire tel qu'un index , et c'est la chose que vous changez). Mais votre exercice est toujours valide; Nous devons simplement en faire un meilleur exercice en demandant «Que devrions-nous devoir changer pour faire une liste susceptible de récursion?» P> Nous devons changer deux choses: (1) rendre la liste immuable, et (2) en faire une structure de données définie de manière récursive. S'il est immuable, vous ne pouvez pas modifier les données de l'appelant par accident; C'est inconnu. Et s'il s'agit d'une structure de données définie de manière récursive, il existe un moyen naturel de réursion sur celui-ci qui est bon marché. P>
Voici votre nouvel exercice: P>
- Un
immutableliste code> est (1) vide ou (2) un seul entier, appelé "Head" et une liste immuable, appelée "queue". Les mettre en œuvre à la manière de choisir. (Classe de base abstraite, interface mise en œuvre par plusieurs classes, classe unique qui fait le tout, tout ce que vous pensez est préférable. Portez une attention particulière aux constructeurs.) Li>immutablelist code> a trois propriétés en lecture seule publiques:bool iSeMTY code>,int Head code> etimmutableliste queue code>. Les mettre en œuvre. Li>- Nous pouvons maintenant définir
int Somme (immutablelist) code> en tant que méthode récursive: le boîtier de base est la somme d'une liste vide est zéro; Le cas inductif est la somme d'une liste non vide est la tête plus la somme de la queue. Mettre en œuvre; pouvez-vous le faire comme une seule ligne de code? LI> ul>Vous en apprendrez beaucoup plus sur C # et la programmation dans un style fonctionnel avec cet exercice. Utilisez des algorithmes itératifs sur
Listecode>, toujours; C'est ce qu'il a été conçu pour. Utilisez la récursion sur les structures de données conçues pour la récursivité. P> Exercices de bonus: P>
- écriture
somme code> comme méthode d'extension, de sorte que vous pouvez appelermyimmutablelist.sum () code>. Li>- la somme est un cas particulier d'une opération appelée
agrégat code>. Il renvoie un entier et prend trois paramètres: une liste immuable, un entier appelé l'accumulateur et unFunccode>. Si la liste est vide, le résultat est l'accumulateur. Sinon, le résultat est la récursion sur la queue et appelant la fonction sur la tête et l'accumulateur. Écrivez un agrégat récursif code>; Si vous avez terminé correctement, alorsint Somme (immutablelist) => Agrégat (éléments, 0, (ACC, élément) => ACC + Item); code> devrait être une implémentation correcte deSomme code>. Li>- genericiser
immutablelist code> àimmutablelistcode>; genericiser agrégat code> àagrégatcode> où t code> est le type d'élément de liste etr code> est le type d'accumulateur . li> ul>
Essayez de cette façon:
int addRecursively(List<int> lst)
{
if(lst.Count() == 0) return 0;
return lst.Take(1).First() + addRecursively(lst.Skip(1).ToList());
}
Combinez 2 éléments de la liste, supprimez un élément de la liste et répétez jusqu'à une valeur - c'est le total
Je ne comprends pas vraiment la question. Si je ne suis pas mal interprété, votre méthode fait exactement ce que vous voulez: cela résume les éléments de la liste, il est récursif (ce qui n'est évidemment pas une chose utile pour résumer une liste) et ne prend que la liste comme argument. Quel est le problème exactement?
Toutes mes excuses, je n'ai pas entré mon erreur. J'ai mis à jour le code. L'erreur est celle qui indique que je saisis dans la fonction qu'il ne renvoie jamais le dernier élément de cette liste plutôt que de renvoyer une somme de ces éléments
Ah maintenant j'ai eu votre "erreur": la méthode retourne i> la valeur correcte. Vous devez vérifier la valeur de retour B>, mais vous ne produisez que une valeur intermédiaire. Supprimer la
console.writeline code> à partir de la méthode et sortie uniquement le résultat résultat b>:console.writeline (addrecursiving (numéros)); code>.Une fois que vous avez réparé cela, vous devez savoir que ce n'est pas considéré comme une bonne pratique pour une méthode qui résume une liste pour supprimer tous les éléments de cette liste dans le processus (à «Mutater»). Vous voudrez peut-être examiner la création de nouveaux tableaux pour transmettre, ou même utiliser la portée.
Et quelque chose que vous devez apprendre dès que vous commencez à apprendre à apprendre la programmation: Débogage B>. Vous pouvez définir des points d'arrêt et traverser votre code d'exécution, regarder les variables modifier leurs valeurs, etc. De cette façon, vous comprenez ce que le code fait exactement et comment cela échoue.
Pourquoi voudriez-vous faire cela? Si vous souhaitez apprendre des fonctions récursives, une tâche réelle qui bénéficie de la récursivité serait plus utile.
Merci rené! Grand surveillance de ma part. Et merci Nathan, je vais avoir un autre aller à cela maintenant.
Savez-vous que ce n'est pas la bonne approche de ce problème?