décomposition en produit de facteur premier

décomposition en produit de facteur premier - Ada - Programmation

Marsh Posté le 30-10-2005 à 16:00:13    

Bonjour
je recherche un programme en ada permettant de décomposer un nombre entier donné par l'utilisateur du programme en son produit de facteurs premiers.
Merci

Reply

Marsh Posté le 30-10-2005 à 16:00:13   

Reply

Marsh Posté le 30-10-2005 à 16:15:31    

Règles de la catégorie.
 
Montre nous un bout de ton code, même s'il ne fonctionne pas du tout, ou même une ébauche d'algorithme si tu es vraiment bloquée, ou pose des questions sur ce que tu ne comprends pas, et on t'aidera ; mais on ne te donnera pas une solution toute faite.

Reply

Marsh Posté le 30-10-2005 à 16:40:13    

En fait je pense etre arriver à trouver tous les diviseur d'un nombre entier. Mais pas les diviseur premier, et je ne sais pas non plus comment faire pour les restituer à la fin.
Voici ce que j'ai déjà fait :
 
with ada.text_io, ada.integer_text_io;
i,p,k = integer;
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
p:=2;
while p<=i/2 loop
   if i rem p = 0  then
      k:=i/p;
      ada.integer_text_io.put(k);
      ada.text_io.put("est un diviseur de :" ); ada.integer_text_io.put(i);
      p:=p+1;
   else
      p:=p+1;
   end if;


Message édité par Profil supprimé le 30-10-2005 à 16:41:01
Reply

Marsh Posté le 30-10-2005 à 17:30:03    

J'ai modifié mon algorithme, je pense que celui ci est correct.
Pouvez vous me dire se que vous en pensez?
 
with ada.text_io, ada.integer_text_io;
i,p,k = integer;
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
p:=2;
while p<=i/2 loop
if i rem p = 0 then
ada.integer_text_io.put(p);
ada.text_io.put("est un facteur premier de :" );
ada.integer_text_io.put(i);
ada.text_io.new_line;
else
p:=p+1;
end if;
end loop;
 
 
Merci

Reply

Marsh Posté le 30-10-2005 à 18:00:36    

Presque bon ;)  
 
Si je te demandais de trouver la décomposition en facteurs premiers de 42 (par exemple), comment t'y prendrais-tu ?
 
Ton raisonnement ressemblerait probablement à ça :
 
"Voyons, 42 est divisible par 2. 2 est un nombre premier, c'est donc un des facteurs premiers que je recherche. Je divise 42 par 2, j'obtiens 21. 21 n'est pas divisible par 2. 21 est divisible par 3. 3 est premier, c'est encore un des facteurs premier recherché. Je divise 21 par 3, j'obtiens 7. 7 ne se divise pas par 2, ni par 3, ni par 4, ni par 5, ni par 6 : il est donc premier. La décompostion de 42 en facteurs premiers est donc 2*3*7."  
 
(toutefois tu ne testerais peut être pas 4, 5 et 6 pour déterminer si 7 est premier si tu connais le crible d'Ératosthène).
 
Essaye ton algorithme sur 42 et vérifie ce qu'il se passe :D Il n'y a vraiment pas grand chose à changer ;)  
 
 
 
Pour la restitution du résultat, je ne suis pas sûr de ce que tu veux dire : est ce que tu recherches un moyen de stocker le résultat dans une variable pour l'afficcher convenablement par la suite ? Dans ce cas, il te suffit d'utiliser un tableau d'entiers où tu stockeras chaque facteur premier que tu trouveras. Je te laisse réfléchir à la taille du tableau (en combien de facteur premiers, au maximum, un nombre n peut il être décomposé ?)

Reply

Marsh Posté le 30-10-2005 à 18:56:28    

En fait ici mon programme va écrire par exemple :
2 est un facteur premier de 18
3 est un facteur premier de 18
3 est un facteur premier de 18.
 
Je voudrais qu'à la fin, il soit marqué :
18 = 2*3^2
 
J'avais déjà pensé à mettre les résultats dans un tableau mais je ne vois pas du tout comment.
De quelle façon puis je stocker les facteurs premier que j'aurai trouvé dans un tableau?

Reply

Marsh Posté le 30-10-2005 à 20:11:09    

begin
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
 
declare
-- déclaration d'un tableau
    Tableau : array (1..taille) of Integer;  -- "taille" doit être un entier. A toi de bien choisr sa valeur
    Index : Integer := 1;
 
begin  
    p := 2
    while -- etc...
       -- si p contient le facteur premier que tu viens de trouver
       Tableau (Index) := p;
       Index := Index + 1;
       -- etc...
 
   end loop;
 
   -- fait attention au dernier facteur premier ! Que se passe-t-il si le nombre entré par l'utilisateur est un nombre premier ?
 
 
   -- pour l'affichage en lui même, je te laisse chercher (n'oublie pas que les facteurs sont classés par ordre croissant)
   -- l'accès aux éléments du tableau se fait ainsi :
   for I in Tableau'First..Index-1 loop
      Ada.Integer_Text_Io.Put (Tableau(I));
   end loop;

Il y a peut être des choses nouvelles pour toi là dedans; si tu ne comprends pas, utilise google ou demande ici.  
 
 
 
 
 
 
 
 
 
 
 
 

Reply

Marsh Posté le 30-10-2005 à 20:53:45    

merci bcp :)
 
est ce que les modifications apporter sont justes?
 
with ada.text_io, ada.integer_text_io;
i,p,k = integer;
index = integer;
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
type t_tableau = array(1..i) of integer;
index:=1;
begin
   p:=2;
   while p<=i/2 loop
      if i rem p = 0  then  -- Calcul du reste de la division de i par p
         tableau(index):=p;
         index:=index+1;
         ada.integer_text_io.put(p);
         ada.text_io.put("est un facteur premier de :" );
         ada.integer_text_io.put(i);
         ada.text_io.new_line;
      else
         p:=p+1;
      end if;
   end loop;
-- Affichage du résultat
   ada.integer_text_io.put(i);
   ada.text_io.put("=" );
   for index in tableau'first..index-1 loop
      ada.text_io.put("*" );
      ada.integer_text_io.put(tableau(index));
   end loop;
   ada.text_io.new_line;
end

Reply

Marsh Posté le 31-10-2005 à 00:12:08    

Commençons par l'implémentation. Déjà, tableau n'est pas déclaré. Ensuite on ne mélange pas déclaration et code en ADA. Si tu veux utiliser un tableau dans ce programme, il va te falloir utiliser declare quelque part.
 
Accessoirement, le type t_tableau est beaucoup trop grand par rapport à ce que tu veux faire.
Si tu t'interesses un peu à la vitesse de l'algorithme pour trouver des nombres premiers cherche "crible d'ératosthène" dans google.
 
En admettant que le bon résultat est dans tableau, ton code afficherait pour 12 :
12 = *2*2*3
Ce qui n'est pas très ésthétique :o  
Il suffit d'afficher la première valeur seule puis de commencer la boucle à tableau'first+1.
 
Ton idée d'afficher le résultat sous la forme 2^2 * 3, si elle n'est pas très simple, présente l'avantage d'être un bon petit exercice supplémentaire pour te familiariser avec les tableaux et t'aider avec les algorithmes. Dans tableau, tu as [ 2 ; 2 ; 3 ]. Tu veux le nombre de deux, le nombre de trois, etc... Comment faire ? Si tu as le temps, je t'encourage à chercher ;)  
 
 
 
 
 
 
 
Maintenant, l'algorithme. Prends une feuille et un crayon, et fait une simulation de ton programme. Choisis une valeur pour i, et marque le changement de valeur des variables au cours du déroulement du programme. Est-ce que le résultat obtenu est le bon ?
 
 
Maintenant tu sais que l'algorithme est incorrect (si tu as trouvé qu'il était correct, va dormir, tu en as besoin [:pingouino]) ; oublie ada un instant, et trouve ce qui ne va pas et ce qu'il aurait fallu changer à l'algorithme pour trouver le bon résultat. Pense aussi au cas où i est un nombre premier.
 
Ensuite, traduis ton nouvel algorithme en ada (cette étape ne te prendra probablement que quelqeus secondes : c'est l'algorithme qui est important).

Reply

Marsh Posté le 31-10-2005 à 11:27:05    

J'ai revu mon programme. Celui ci est il plus correct?
 

with ada.text_io, ada.integer_text_io;
i,p,k = integer;
index = integer;
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
tableau : array(1..i) of integer;
index:=1;
begin
   k:=i;
   p:=2;
   while p<=k/2 loop  -- recherche des facteurs premiers
      if i rem p = 0  then  -- Calcul du reste de la division de i par p
         tableau(index):=p;
         index:=index+1;
         ada.integer_text_io.put(p);
         ada.text_io.put("est un facteur premier de :" );
         ada.integer_text_io.put(i);
         ada.text_io.new_line;
         k:=k/p;
      else
         p:=p+1;
      end if;
   end loop;
-- Affichage du résultat
   ada.integer_text_io.put(i);
   ada.text_io.put("=" );
   ada.integer_text_io.put(tableau(1));
   for index in tableau'first+1..index-1 loop
      ada.text_io.put("*" );
      ada.integer_text_io.put(tableau(index));
   end loop;
   ada.text_io.new_line;
end;


Reply

Marsh Posté le 31-10-2005 à 11:27:05   

Reply

Marsh Posté le 31-10-2005 à 12:09:07    

Que se passe-t-il si i est un nombre premier ?

Reply

Marsh Posté le 31-10-2005 à 12:25:42    

Si i est premier, rien ne vas s'afficher.
Il faut donc, je pense, rajouter qqch qui va dire que si i est permier alors c'est un facteur premier de i.
 
Mais je ne vois pas comment dire en ada qu'un nombre est premier. Vu qu'un nombre prmier n'est divisible que par lui meme et par un, je ne peux pas faire une boucle jusqu'à l'infini...

Reply

Marsh Posté le 31-10-2005 à 12:30:51    

Quelle est la valeur de k à la fin de la boucle avec i=5, i=7 et i=12 ?

Reply

Marsh Posté le 31-10-2005 à 14:12:47    

Si i=5, k=5
Si i=7, k=7
Si i=12, k=3
 
J'ai refais mon programme, qu'en pensez vous?
Merci
 

with ada.text_io, ada.integer_text_io;
i,p,k : integer;
index : integer;
ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
ada.text_io.new_line;
tableau : array(1..i) of integer;
index:=1;
begin
   k:=i;
   p:=2;
   while p<=k/2 loop  -- recherche des facteurs premiers
      if k rem p = 0  then  -- Calcul du reste de la division de i par p
         tableau(index):=p;
         index:=index+1;
         ada.integer_text_io.put(p);
         ada.text_io.put("est un facteur premier de :" );
         ada.integer_text_io.put(i);
         ada.text_io.new_line;
         k:=k/p;
      else
         p:=p+1;
      end if;
   end loop;
   if k=i then
      ada.integer_text_io.put(i);ada.text_io.put("est un nombre premier" );
   else
      tableau(index):=k;
      ada.integer_text_io.put(k); ada.text_io.put("est un facteur premier de :" );
      ada.integer_text_io.put(i);
-- Affichage du résultat
      ada.integer_text_io.put(i);
      ada.text_io.put("=" );
      ada.integer_text_io.put(tableau(1));
      for index in tableau'first+1..index-1 loop
         ada.text_io.put("*" );
         ada.integer_text_io.put(tableau(index));
      end loop;
      ada.text_io.new_line;
   end if;
end

Reply

Marsh Posté le 31-10-2005 à 15:16:50    

Presque bon.
 
 
Tu ne peux pas mélanger les déclarations et les instructions en ada. Lorsqu'on veut déclarer une nouvelle valeur au milieu d'instructions, il faut créer un nouveau bloc avec declare.
 
Le début de ton code devrait ressembler à ça :

with ada.text_io, ada.integer_text_io;  
 
procedure facteurs_premiers is
   i,p,k : integer;
   index : integer;
 
begin
   ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
   ada.text_io.new_line;
 
   declare
      tableau : array(1..i) of integer;
   begin
      index:=1;
      k:=i;
      p:=2;
      while p<=k/2 loop


 
Ensuite dans ta boucle d'affichage tu as deux problèmes :
- tu as appelé ta variable de boucle index. Or, index existe déjà et tu en as besoin dans ta boucle (pour vérifier si elle est terminée).  
- Tu t'arrêtes à index-1. A quel endroit se situe la dernière valeur dans tableau ? La réponse est quelques lignes au dessus, juste après la boucle :

       tableau(index):=k;

Est ce que tu modifies la valeur de index dans la suite du code ?

Reply

Marsh Posté le 31-10-2005 à 16:27:47    

tableau(index):=k;


Donc la valeur de index est fixe par la suite.  
Ainsi je remplace mon index-1 par k et je pense que c'est ok :

  for n in tableau'first+1..k loop
         ada.text_io.put("*" );
         ada.integer_text_io.put(tableau(n));
   end loop;

Reply

Marsh Posté le 31-10-2005 à 16:34:56    

est-il possible en ADA de générer des tableaux de taille variable? (edit: oui, les unconstrained arrays)
 
Et as-tu un framework de tests unitaires dispo (parce que la décomposition en facteurs premiers ça marche très bien pour une introduction aux tests unitaires, même si ça ne donne pas nécessairement la solution la plus efficace, je doute que ce soit le but ici)


Message édité par masklinn le 31-10-2005 à 16:38:23

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 31-10-2005 à 16:39:47    

Eh bien moi je débute à peine dans la programmation, maintenant je pense que c possible de faire des tableaux de taille variable à partir du moment ou celui ci est fini.
 
Sinon je ne sais pas ce qu'est un "framework"

Reply

Marsh Posté le 31-10-2005 à 16:53:01    

Un "framework", c'est simplement un terme désignant une structure générique. Cette structure va mettre à la disposition du programmeur un certain nombre d'outils pour remplir des tâches précises, mais à tendance à limiter le dit programmeur. C'est très souvent utilisé sur les gros sites web professionnels. L'opposé de l'approche "framework" c'est l'approche "library", dans laquelle on va plutôt étendre ses possibilités par l'ajout de libs.
 
Le framework a pour but de simplifier mais limite, l'approche library simplifie largement moins mais elle pose également moins de limite (aucune en fait, sauf les limites du codeurs lui même).
 
Le principe d'un framework de test unitaire, c'est principalement de permettre de tester les entrées et sorties de chaque fonction afin d'être sûr à tout moment qu'elle fait ce qu'on lui a demandé.
 
Par exemple sur une fonction de décomposition en facteurs premiers, on va tester si en lui donnant "2" la fonction ressort bien "2", "3" pour "3", "2, 2" pour "4", etc jusqu'à considérer qu'on ne risque plus de problème.
 
Pour Ada (/GNAT), j'ai trouve AUnit, un framework de type xUnit (avec une intro à AUnit).
 
Si tu veux plus d'informations sur les tests unitaires, l'article de la wikipedia est une intro potable
 
Les tests unitaires sont l'une des bases de la programmation "TDD", c'est à dire la programmation "menée par les tests" (test-driven development)


Message édité par masklinn le 31-10-2005 à 16:54:11

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-11-2005 à 16:22:24    

J'ai refais mon programme, je suis enfin arrivé à le tester mais il y a toujours un problème avec le tableau.
Les lignes incorrectes sont :

tableau(x):=p;

et

ada.text_io.put(tableau(1));

Mais je n'arrive pas à trouver les erreurs
Voici mon programme en entier:

with ada.text_io, ada.integer_text_io;
procedure facteur is
   i,p,k,n : integer;
   x : integer;
   type Tableau is array(1..i) of Integer;
begin
   ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
   ada.text_io.new_line;
   x:=1;
   k:=i;
   p:=2;
   while p<=k/2 loop  -- recherche des facteurs premiers
      if k rem p = 0  then  -- Calcul du reste de la division de i par p
         tableau(x):=p;
         x:=x+1;
         ada.integer_text_io.put(p);
         ada.text_io.put("est un facteur premier de :" );
         ada.integer_text_io.put(i);
         ada.text_io.new_line;
         k:=k/p;
      else
         p:=p+1;
      end if;
   end loop;
   if k=i then
      ada.integer_text_io.put(i);ada.text_io.put("est un nombre premier" );
   else
      tableau(x):=k;
      Ada.Integer_Text_Io.Put(K); Ada.Text_Io.Put("est un facteur premier de :" );
      ada.integer_text_io.put(i);
-- Affichage du resultat
      ada.integer_text_io.put(i);
      ada.text_io.put("=" );
      ada.text_io.put(tableau(1));
      for N in Tableau'First+1..K Loop
         ada.text_io.put("*" );
         ada.text_io.put(tableau(n));
      end loop;
      ada.text_io.new_line;
   end if;
end;

Reply

Marsh Posté le 01-11-2005 à 16:26:10    

T'as défini un type de tableau, mais t'as pas créé de variable implémentant ce type :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-11-2005 à 16:40:02    

J'ai pas tout compris... :s

Reply

Marsh Posté le 01-11-2005 à 16:46:18    

type Tableau is array(1..i) of Integer;


Ca, ca crée un type de tableau, ça permet de définir des tableaux allant de 1 à i, mais ça ne crée pas un tableau.
 
Pour créer un tableau à partir de ça, il te faut ensuite mettre

tab : tableau


qui va générer une variable "tab" de type "tableau"


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 01-11-2005 à 16:48:59    

Ah d'accord je ne le savais pas.
Merci :)

Reply

Marsh Posté le 01-11-2005 à 16:55:38    

J'ai modifié les erreurs de mon programme, mais je n'arrive pas à l'exécuter. Ca me marque : raised storage_error 14 object too large
Qu'est ce que celà signifie?
 

with ada.text_io, ada.integer_text_io;
procedure facteur is
   i,p,k,n,x : integer;
   type Tableau is array(1..i) of Integer;
   T : Tableau;
begin
   ada.text_io.put("saisie d'un nombre =" ); ada.integer_text_io.get(i);
   ada.text_io.new_line;
   x:=1;
   k:=i;
   p:=2;
   while p<=k/2 loop  -- recherche des facteurs premiers
      if k rem p = 0  then  -- Calcul du reste de la division de i par p
         T(x):=p;
         x:=x+1;
         ada.integer_text_io.put(p);
         ada.text_io.put("est un facteur premier de :" );
         ada.integer_text_io.put(i);
         ada.text_io.new_line;
         k:=k/p;
      else
         p:=p+1;
      end if;
   end loop;
   if k=i then
      ada.integer_text_io.put(i);ada.text_io.put("est un nombre premier" );
   else
      T(x):=k;
      Ada.Integer_Text_Io.Put(k); Ada.Text_Io.Put("est un facteur premier de :" );
      ada.integer_text_io.put(i);
-- Affichage du resultat
      ada.integer_text_io.put(i);
      ada.text_io.put("=" );
      ada.integer_text_io.put(T(1));
      for n in Tableau'First+1..k loop
         ada.text_io.put("*" );
         ada.integer_text_io.put(T(n));
      end loop;
      ada.text_io.new_line;
   end if;
end;

Reply

Marsh Posté le 01-11-2005 à 16:58:00    

Je t'ai dit de compiler avec -gnatv et -gnatwa :o
 
Et j'ai pas les mêmes erreurs que toi [:pingouino]


Message édité par masklinn le 01-11-2005 à 16:58:16

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed