Partage
  • Partager sur Facebook
  • Partager sur Twitter

Algorithme

Aide

11 novembre 2020 à 23:08:53

Bonsoir,

J'éprouve de nombreux problèmes sur un ensemble d'exercices traitant d’algorithmes (je suis très mauvais comprendre la logique du langage). Si vous accepté de m'aider, je vous les présenterai un par un. Voici le premier sur lequel j'éprouve des difficultés (et oui ce n'est que le deuxième).

Je vous remercie par avance de votre aide.

Question2. Avant de multiplier, additionnons ! Quel est le résultat de l’addition 001011012 + 001100112 ? écrivez l’algorithme d’addition de 2 entiers représentés sur un octet :

Algorithme :addition

Données :ta: Tableau de Nombre, tb: Tableau de Nombre, 2 tableaux de taille 8 ; ces tableaux sont les représentations binaires de deux entiers a et b.

Résultat :Tableau de Nombre, tableau de taille 8 qui est la représentation binaire de l’entier a+b.

Et voici mes avancées en la matière :

001011012 + 001100112 = (32+8+4+1= + (32+16+2+1) = 45 + 51 = 96

Algorithme :addition

Données :ta: Tableau de Nombre, tb: Tableau de Nombre, 2 tableaux de taille 8 ; ces tableaux sont les représentations binaires de deux entiers a et b.

Résultat :Tableau de Nombre, tableau de taille 8 qui est la représentation binaire de l’entier a+b.

Pour i allant de 0 à 1

        si (a+b) mod2==0

       i==0

      sinon i==1

     fin si

Le résultat est : tc

fin algorithme

Est-ce correct ?
  • Partager sur Facebook
  • Partager sur Twitter
12 novembre 2020 à 8:51:58

Ton addition donne le bon résultat mais la méthode est trop compliqué pour rien. Surtout que je pense qu'il faut que tu écrives le résultat en binaire. Donc au lieu de faire 2 conversion B2 -> B10, puis des calculs, puis une conversion B10 -> B2, fait directement ton addition en binaire, en plus ça te donne la réponse pour la question suivante.

Comment calculer en binaire ?

Rien de bien compliqué, c'est exactement comme en base 10 (ce que tu faisait jusqu'au collège en posant les nombres l'un au dessus de l'autre), à la seule exception près que la retenue s'effectue modulo 2 et pas modulo 10.

Exemple: 0011 + 1001

i) On pose les nombres l'un au dessus de l'autre

  0011
+1001

ii) On additionne terme à terme

  0011
+1001
 ------
  1012

iii) On fait remonter la retenue de droite à gauche

Formellement, on ajoute à chaque terme celui à droite divisé (div entière) par 2, et le terme de droite devient son modulo par 2

(On peut également se dire qu'en base 2, ...02... est égal à ...10...)

Appliquons: 1012 => 1020 => 1100 => plus de 2 = c'est fini.

(Tu pouvais aussi faire les retenues de tête, mais là on essaye de faire les deux question en même temps).

Maintenant que tu connait l'algorithme basique d'addition en binaire, je te laisse le réécrire en pseudo-code.

  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

12 novembre 2020 à 15:44:14

D'accord, merci. Donc ici 00101101(2) + 00110011(2) = 0110000(2) n'est-ce pas ?

Concernant l'écriture de l'algorithme, est-ce correct ? On m'a dit que "dans l'ensemble" c'était correct, sauf que je n'avais pas le droit d'inclure les tableaux a et b ainsi, sans me donner plus de détails...

  • Partager sur Facebook
  • Partager sur Twitter
12 novembre 2020 à 21:38:43

AurélienBouillod a écrit:

D'accord, merci. Donc ici 00101101(2) + 00110011(2) = 0110000(2) n'est-ce pas ?

Presque, il manque un 0 à la fin, mais je pense que c'est une faute de frappe.

Pour ce qui est de l'algorithme, il n'a pas de sens... C'est pour ça que je t'avais proposé de le refaire.

Tu créer une boucle "pour" sans "fin pour" donc déjà, erreur de syntaxe. Mais en plus, tu fait n'importe quoi avec l'indice, en plus de confondre le "=" avec le "==". Ensuite, tu n'as pas accès aux données a et b, seulement ta et tb, leur représentation binaires respectives*. Enfin, tu retournes la valeur de tc, or tu ne l'a pas définis et ce n'est pas une entrée, tu retournes donc quelque chose qui n'existe pas.

Ce que ton algorithme est censé faire, si j'ai bien compris, est de créer un tableau tc qui représente l'addition binaire de a et b, représentés par ta et tb.

Je pense donc qu'il faut que tu reprennes à 0 et que tu revois bien le principe de boucle "pour" et la différence entre l'égalité logique("==") et l'affectation("="). Et pense à déclarer les variables que tu utilises !!! Dans aucun langage de programmation, tu peux utiliser des variables que tu n'as pas défini.

*par "représentation binaire", je pense que l'énoncé entend "tableau de 8 entiers 0 ou 1 qui correspondent au nombre binaire associé"

Par exemple: si a = 5(10) = 00000101(2) alors ta ={0,0,0,0,0,1,0,1}

  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

12 novembre 2020 à 22:37:39

D'accord, je réessaye selon le peu que j'ai compris via internet (le plus de temps j'y passe, le moins je n'y comprends quoi que ce soit...).


Algorithme :addition

Données : n : Nombre ; c : Nombre

Résultat : tab : tableau de nombres de taille 8

Pour i allant de taille(tab)-1 à 0 faire

        tab[i]:= n mod c;

        n:= n quo c;

  fin pour

Le résultat est : tab

fin algorithme


Est-ce correct ?
  • Partager sur Facebook
  • Partager sur Twitter
12 novembre 2020 à 23:28:32

Non, mais c'est sur une très bonne voie. Le raisonnement est bien, et la boucle "pour" et parfaite, mais il faut que tu l'applique avec 2 tableaux en entrée, donc au lieu de comparer le ième terme du tableau avec un nombre, il faudra comparer le ième terme du premier tableau avec le ième terme du second. et "quo" c'est quoi ? la division entière ?

-
Edité par NiwdEE 12 novembre 2020 à 23:31:02

  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

12 novembre 2020 à 23:59:21

Pour quo oui c'est la division entière.


Algorithme :addition

Données : n : tableau 1 ; c : tableau 2

Résultat : tab : tableau de nombres de taille 8

Pour i allant de taille(tab)-1 à 0 faire

        tab[i]:= n mod c;

        n:= n quo c;

  fin pour

Le résultat est : tab

fin algorithme


Est-ce correct ?
  • Partager sur Facebook
  • Partager sur Twitter
13 novembre 2020 à 4:10:45

Salut,
Désolé de m'immiscer dans votre conversation ...
L'algorithme est censé faire l'addition de deux nombres représentés dans deux tableaux sous forme binaire, j'ai bien compris?
Il me semble que cela été montré comment faire.
Si je le faisais à la main, je ferais comme ceci.
D'abord, je n'ai pas de retenue, elle est donc 0.
Ensuite j'additionne chaque chiffre en partant du moins significatif en allant vers le plus significatif (de taille-1 à 0)
Que vaut le terme du résultat?
Il vaut la somme des deux, mais s'il est égal ou dépasse 2, ou bien je soustrait 2, ou bien je fais un modulo 2
Comment je calcule la retenue pour le prochain terme?
Elle est égale à la somme divisée (division entière) par 2.
Donc, en fait, à chaque étape, je dois additionner les deux termes plus la retenue du terme précédent.
Puisque chacun des deux termes et la retenue ne peuvent prendre que 0 ou 1 comme valeur, la somme des trois éléments ne peut pas dépasser 3.
Je te laisse mettre ça en algorithme.
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

13 novembre 2020 à 8:43:15

AurélienBouillod a écrit:

        tab[i]:= n mod c;

        n:= n quo c;


n et c sont des tableaux, il faut donc que tu précises, avec des crochets, le terme sur lequel tu fais les opération.

Et cet algorithme ne marchera pas. Essaye juste de reproduire étapes par étapes la méthode que je t'ai donné, mais traduite en pseudo-code. 



  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

13 novembre 2020 à 14:03:51

Désolé, je n'y comprends plus rien.
  • Partager sur Facebook
  • Partager sur Twitter
13 novembre 2020 à 19:52:52

Tu sembles savoir à quoi sert tab[i]. À quoi pourrait bien servir n[i] ou c[i]?
Je n'ai pas vu ta retenue dans ton code.
Que veulent dire les opérateurs  mod  et quo ? ('modulo' et 'quotient')
Pas certain que ce soit une bonne idée de dire que la longueur est 8. Ça pourrait être n'importe quelle longueur. Mais il faut la fournir à la fonction.
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

13 novembre 2020 à 23:34:12

La longueur se dot d'être 8 : on me demande de produire un octet.

Qu'est-ce qu'une retenue dans un code ?

Je réessaye pour l'algorithme :

Algorithme :addition

Données : n : tableau 1 ; c : tableau 2

Résultat : tab : tableau de nombres de taille 8

Pour i allant de taille(tab)-1 à 0 faire

        tab[i]:= n[i] + c[i];

  fin pour

Le résultat est : tab

fin algorithme


Est-ce correct ?

  • Partager sur Facebook
  • Partager sur Twitter
14 novembre 2020 à 1:39:08

Quand tu étais enfant et qu'on te montrait à faire des additions à l'école, comment additionnais-tu 19 + 13 ?
Tu faisais 9 + 3 = 12, Tu plaçais  2 et tu ajoutais 1 à la deuxième colonne,
donc 1 + 1 + 1 = 3. Résultat: 32
C'est ça la retenue.
Les ordinateurs sont comme des enfants, il faut tout leur dire ...
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

14 novembre 2020 à 13:42:42

Algorithme :addition

Données : n : tableau 1 ; c : tableau 2

Résultat : tab : tableau de nombres de taille 8

Pour i allant de taille(tab)-1 à 0 faire

        tab[i]:= n[i] + c[i];

        si i==2

            tab[i]:= 0, tab[i+1]:= 1;

        fin si

  fin pour

Le résultat est : tab

fin algorithme


Est-ce correct ?
  • Partager sur Facebook
  • Partager sur Twitter
14 novembre 2020 à 15:22:50

Bonjour,

Non, ce n'est pas correct (mais y'a de l'idée). Tu mélanges encore un peu tout, mais je pense comme @PierrotLeFou et @NiwdEE que tu ne poses pas assez les choses (tu veux trop vite passer à l'écriture en langage naturel) et il y a un manque de méthode dans la résolution de problème. Poser les choses, résoudre des problèmes (notamment d'algorithmie), ça se fait avec d'abord avec du papier et des stylos. Ça demande un peu de patience et d'accepter que la solution ne vienne pas directement (ce qui implique de savoir aussi faire des pauses et faire autre chose pour laisser les choses se décanter).

Le point de départ, c'est de vraiment faire une addition binaire à la main en la posant comme ça:

  10101110
+ 01000101
__________

Quand tu fais ça, sans t'en rendre compte tu vas exécuter l'algorithme qui t'es demandé d'écrire (donc quand tu fais ça la machine c'est toi, sauf que tu es beaucoup plus intelligent que la machine). Donc l'algo tu le connais, ce qu'on te demande, et c'est c'est là la difficulté, c'est de la traduire dans un langage compréhensible par une machine.

Si l'algorithme ne t’apparaît pas: écrit le, avec des mots en faisant des phrases, tout ce que tu fais pour partir de la situation initiale et arriver au résultat. Quand je dis tout, c'est bien tout, essaye d'être le plus précis possible, de ne négliger aucun détail (parce que les détails, pour une machine c'est important). L'idée est de découper le problème en de plus petits problèmes, et de découper ces nouveaux problèmes jusqu'à arriver à des choses que tu pourras exprimer simplement en langage naturel.

Tu devrais alors voir que beaucoup de tes actions se ressemblent/se répètent comme une boucle. Ensuite, essaye de résumer ces actions le plus simplement possible, petit à petit, tu te rapprochera du langage naturel.

Par ailleurs, les algo que tu proposes, tu peux les faire «tourner» à la main facilement. En faisant cela, tu verrais rapidement qu'ils sont faux (parce que tu arriveras à des incohérence ou à un résultat faux).

Par exemple, pour faire tourner ta boucle Pour, on va faire un tableau, avec une ligne pour chaque valeur que i prend, ensuite tu as quasiment autant de colonne que de variable utilisées/opérations faites dans ta boucle.

Ici tes colonnes ressembleraient à ça.

i | n[i] | c[i] | tab[i](= n[i] + c[i]) | i == 2 (valeur booléenne) | i + 1 | tab[i+1]

Si tu fais ça, tu devrais vite t'apercevoir d'incohérence dans ton raisonnement et voir ce qu'il faut modifier. C'est la méthode essai-erreur (trial-error en anglais): https://fr.wikipedia.org/wiki/M%C3%A9thode_essai-erreur.

-
Edité par KoaTao 14 novembre 2020 à 15:46:58

  • Partager sur Facebook
  • Partager sur Twitter
14 novembre 2020 à 15:54:00

C'et Parfait ! Nan je déconne c'est faux, mais il manque juste 2 petits trucs pour que l'aglo marche et je te les donne parce que t'as déjà bien taffé et c'est pas évident.

Déjà, il faut que tu initialise ton tab avec toutes ses valeurs à 0, pour faire des opération avec tab[i] sans lui affecter de valeur au préalable.

Ensuite, il faut que tu remplaces ton "tab[i] = n[i] + c[i]" par "tab[i] += n[i] + c[i]" (ou "tab[i] = tab[i] + n[i] + c[i]" si tu préfères). Cela te permet de compter les retenues précédentes quand tu fais l'addition d'un terme.

Enfin, il faut que tu remplaces ton si i==2, par si i>1 (ou i >=1) car si on a 1+1 et une retenue, ça peut être 3, et comme on l'a dit, la formule est tab[i+1] = tab[i] div 2, tab[i] = tab[i] mod 2 (dans cet ordre)

Et surtout: Pense à tester tes algorithmes avec des valeurs différentes pour voir si ils fonctionnent, et sinon pour voir d'où viens le problème.

  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

14 novembre 2020 à 16:18:15

NiwdEE a écrit:

Enfin, il faut que tu remplaces ton si i==2, par si i>1 (ou i >=1) car si on a 1+1 et une retenue, ça peut être 3, et comme on l'a dit, la formule est tab[i+1] = tab[i] div 2, tab[i] = tab[i] mod 2 (dans cet ordre)

Comme quoi, ce n'est pas si évident, parce que c'est faux aussi.

Dans la condition on retrouverai alors:

Si ( tab[i] >= 2 ) {
    retenue = 1
    tab[i] = tab[i] mod 2
} sinon {
    retenue = 0
}

donc pas de condition avec i évidemment (inattention celle là) et il ne faut pas faire tab[i+1] parce que lorsque i vaut 7 (donc à la 8ème itération de la boucle), i+1 vaut 8 et tab[8] est en dehors des limites du tableau ce qui donnerai une erreur à chaque fois. L'utilisation d'une variable retenue est plus indiqué (ce qui se rapproche plus de ce qui est utilisé en pratique avec l'overflow et le carry).

Ce qui implique de faire déclarer retenue avant la boucle et de l'initialiser à 0, et de faire tab[i] = n[i] + c[i] + retenue.

On peut remarquer qu'on peut donc trouver un résultat incohérent lorsque qu'on additionne 1000 0000 avec 1000 0000 par exemple qui donne 0000 0000 avec notre algorithme parce que le résultat dépasse les limites du tableau. L'exercice est donc vraiment subtile je trouve pour débuter en algorithmie ^^ .

-
Edité par KoaTao 14 novembre 2020 à 16:28:03

  • Partager sur Facebook
  • Partager sur Twitter
14 novembre 2020 à 16:26:12

My bad, j'ai évidemment voulu dire tab[i] et pas i
  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

14 novembre 2020 à 18:15:26

@NiwdEE:
Pourquoi suggèrais-tu d'initialiser tab au départ?
Pour un non habitué, il est difficile de suggérer la bonne façon de calculer la somme et la retenue.
Ou bien on dit qu'il faut utiliser le modulo et le quotient.
Ou bien on vérifie si c'est 2 ou plus et on soustrait 2 au nombre et on met la retenue à 1.
Pour un ordinateur, la méthode modulo / quotient est la plus simple.
Mais pour un humain non initié, le test si plus grand que 1 est plus compréhensible.
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

14 novembre 2020 à 18:22:47

@PierrotLeFou:

L’initialisation du tableau est nécessaire pour avoir le droit d’incrémenter les termes (le +=)

En l’occurrence, la modulo et le quotient servent à convertir un 02 en 10 et un 03 en 11 de manière générale, sans avoir besoin de tester deux conditions différentes (techniquement on a même plus "besoin" de conditions mais c'est plus clair et optimisé). Et je me permet de lui dire sans explications car je l'avais déjà évoqué dans ma méthode pour calculer l'addition.

  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"

14 novembre 2020 à 19:06:49

Et cela ne marcherais pas? Je n'ai pas initialisé tab.
Algorithme :addition
Données : n : tableau 1 ; c : tableau 2
Résultat : tab : tableau de nombres de taille 8
    retenue:= 0;
    Pour i allant de taille(tab)-1 à 0 faire
        tab[i]:= n[i] + c[i] + retenue;
        retenue:= tab[i] quo 2;
        tab[i]:= tab[i] mod 2;
  fin pour
Le résultat est : tab
fin algorithme
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

14 novembre 2020 à 22:40:48

Oui, cet algorithme me semble parfaitement correct. En l'occurrence, l'utilisation de la variable "retenue" rend facultative l'initialisation de tab, donc pas problème.
  • Partager sur Facebook
  • Partager sur Twitter

"Si ce n'est pas dur, ce n'est pas intéressant"