construire un arbre n-aire - Delphi/Pascal - Programmation
Marsh Posté le 15-10-2005 à 19:08:01
Salut,
Déja sans regarder en detail ton source, intéraisse toi de plus prêt au Constructeur et Destructeur de classe.
Le probleme ne vient peut etre pas de la mais:
1/ Il me semble que tous objet (class) est dérivé de TObject, donc dans tes cosntructeur si tu n'appelle pas le cosntructeur de l'ancetre ca peut peut etre pas trop le faire ( un truc du genre inherited Create.. dans le create de tes objets)
2/ N'appelle pas la methode destroy directement, utilise Free car elle vérifie si l'instance existe ou pas avant la destruction.
Ensuite je regarderais quand j'aurrais plsu de temps..
a++
bon courage
Heanium
Marsh Posté le 15-10-2005 à 23:38:48
1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble
2/ elle vérifie si le pointeur est nil, pas si l'instance existe. L'instance peut ne plus exister même si le pointeur est non nil. Par ex deux Free de suite sur une même variable ça appellera deux fois le destructeur (et donc ça a des chances d'exploser)
Marsh Posté le 16-10-2005 à 11:11:06
"1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble"
Bon ca c'est une histoire de rigueur dans le code, tu va pas faire une exception pour TObject meme si c'est optionnel, comme ca tu gardes une certaine coherence dans ton source, perso je te conseille de le mettre, ca mange pas de paine et c'est plus sûr (j'en ai déja fait les frais)
"2/ elle vérifie si le pointeur est nil, pas si l'instance existe. L'instance peut ne plus exister même si le pointeur est non nil. Par ex deux Free de suite sur une même variable ça appellera deux fois le destructeur (et donc ça a des chances d'exploser)"
Bien sur que nil.free ca le fait pas ca va de soie mais c'est pas le probleme ici...
De toute facon on n'utilise quazi jamais le Destroy directement dans ton Destroy appelle des Free (sauf le inherited ca va de soie).
C'est aussi une histoire de rigueure...
A++
Marsh Posté le 16-10-2005 à 13:35:37
hexanium a écrit : "1/ pour ceux qui dérivent de TObject directement, l'inherited n'est pas obligatoire il me semble" |
Oui c'est clair, je voulais juste dire que ça n'était pas la source du problème Mais si on l'oublie dans un Form ou autre objet complexe... boum
hexanium a écrit : |
D'accord aussi, jamais d'appel à destroy directement, c'était pour préciser l'histoire d'instance qui existe
Dans Delphi 7 il vaut même mieux utiliser FreeAndNil(obj) au lieu de obj.Free s'il y a un risque de manipuler le pointeur plus tard : au moins on est sûr qu'il est à nil lorsqu'il est détruit.
Marsh Posté le 16-10-2005 à 13:58:11
antp a écrit : Dans Delphi 7 il vaut même mieux utiliser FreeAndNil(obj) au lieu de obj.Free s'il y a un risque de manipuler le pointeur plus tard : au moins on est sûr qu'il est à nil lorsqu'il est détruit. |
merci pour le tips
Marsh Posté le 17-10-2005 à 01:10:57
Salut,
Bien le FreeAndNil(), connaissais pas, merci Antp
Mamodel, peux tu détailler un peu plus ton n-aire je vois pas bien ce que tu veux en faire perso...
A++
Marsh Posté le 17-10-2005 à 12:56:38
en faite je veux construire un arbre n-aire dont les noeuds sont les item et chaque Chemin représente une transaction T[i] alors la j'avais le problème comment relier un noued donner avec ces fils mais bon j'ai essayer un truc qui ressemble a ce que je veux (http://recursivite.developpez.com/?page=page_8#LVII-D ) et ca marche trés bien mais la je dois afficher les chemins contenat un item donné je ne sais si vous avez un algorithm qui fait ca .
Merci
Marsh Posté le 13-10-2005 à 01:51:53
Hello,
J'ai fait ce code a fin de construire un arbre n-aire dont la racine "NULL" et les noued sont les produits(Riz,pain,....). mais toujour j'ai un problème au niveau du code entre // ============= // .
Si le nud tque N.item=debut existe déjà dans larbre on incrémente le count de ce noeud sinon Créer un nouveau nud N N.count = 1 et Créer le lien de parenté entre le nud N et Tree tel que Tree soit le père de N
count : la fréquence de chaque item (exemple Riz est 4) par rapport aux T[i].
Merci de m'aider a résoudre ce problème sachant que j'ai fait plusieurs code mais toujours j'ai un message "violation d'accès à l'adresse 0045E7E dans le module..»
le code :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
//const taille=5;
type
Noeud=
class
private
Fils : array[1..5] of Noeud; //liste de fils
item :string;
count : integer;
//lien : Noeud;
public
constructor create ;
destructor destroy ;
end; { Noeud }
Arbre =
class
private
tete,courant : noeud ;
public
constructor create ;
destructor destroy ;override ;
procedure insert_Tree(Chaine: string);
procedure buildTree();
end ;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;
var
Form1: TForm1;
Tree1 : Arbre;
implementation
{$R *.dfm}
constructor noeud.create ;
var i : integer ;
begin
for i:=0 to 5 do
fils[i]:=nil ;
item:='NULL' ;
count :=0;
//lien:='NULL';
end ;
destructor noeud.destroy ;
var i : integer ;
begin
for i:=0 to 5 do
if fils[i]<>nil then fils[i].destroy ;
inherited destroy ;
end ;
constructor arbre.create ;
begin
tete:=noeud.create ;
courant:=tete ;
end ;
destructor arbre.destroy ;
begin
tete.destroy ;
inherited destroy ;
end ;
procedure arbre.insert_Tree(Chaine: string);
const Delimiteur=',';
var Debut, Fin: string;
k: integer;
begin
// Récupère Début et Fin
k:=Pos(Delimiteur,Chaine);
if k=0 then
begin
Debut:=Chaine; Fin:='';
end
else
begin
Debut:=Copy(Chaine, 1, k-1);
Fin:=Copy(Chaine, k+1, length(Chaine)-k);
end;
//============== Problème a ce niveau =============
if courant.item=Debut then // Si le nud tque N.item=debut existe déjà dans larbre on incrémente le count de ce noeud
begin // Debut = élément a ajouter
inc(courant.count);
courant:=courant.Fils[??]
end
else
begin
courant.fils[??]:=noeud.create ; //nouveau noeud
courant:=courant.fils[??] ;
courant.item:=Debut ;
courant.count:=1;
end ;
//============================================//
// ShowMessage(Debut);
// en s'arrete lorsque la liste est vide
if Fin='' then exit else insert_Tree(Fin);
end;
procedure arbre.buildTree();
const NbElements= 5;
var T: array[1..NbElements] of string;
i: integer;
begin
T[1]:='Riz,Pain,Eau';
T[2]:='Riz,Pain';
T[3]:='Eau,sucre';
T[4]:='Riz,Pain,Sucre';
T[5]:='Riz,Pain,Eau,Sucre';
courant:=tete ;
for i:=1 to NbElements do insert_Tree(T[i]);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Tree1:=arbre.create ;
end;
procedure TForm1.Button1Click(Sender: TObject);
Begin
Tree1.buildTree();
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Tree1.Destroy;
end;
end.
cordialement.