cloudddd a écrit :
char* maj(char* algo,char c,int oui)
{
char *membre,*tmp;
unsigned int i=0,j,m,compte1=0,compte2=0,a;
// supprimes les membres contenant le char c.
while((algo[i]!='\0')&&(algo[0]!='\0'))
{
m=0;
if(algo[i]=='&') i++;
membre=copymembre(algo,i);
for(j=0;j<strlen(membre);j++)
{
if(((membre[j]==c)&&(membre[j-1]!='!')&&(oui==1))||
((membre[j]==c)&&(membre[j-1]=='!')&&(oui==0)))
{
algo=supprmembr(membre,algo);
i=0;
m=1;
}
}
if(m==0) i=i+strlen(membre);
init(membre,strlen(membre));
free(membre);
}
i=0;
m=0;
// compte les membres.
membre=copymembre(algo,i);
if(membre[0]!='\0')
do
{
i=i+strlen(membre);
if(algo[i]=='&') i++;
compte1++;
init(membre,strlen(membre));
free(membre);
membre=copymembre(algo,i);
}while((i==0)||(membre[0]!='\0'));
i=0;
a=strlen(algo);
while(algo[i]!='\0')
{
// supprimes les membres opposé aux membres validé (ex: si c = a, on supprimera tous les !a)
if((algo[i]==c)&&(((oui==0)&&(algo[i-1]!='!'))
||((oui==1)&&(algo[i-1]=='!'))))
{
j=i+1;
if(((algo[i+1]==')'))&&((algo[i-1]=='(')||(algo[i-2]=='(')))
{
if(algo[i-2]=='(')
{
j=i+2;
i=i-3;
}
else
{
j=i+2;
i=i-3;
}
}
else if(oui==1) i=i-1; if(algo[j+1]=='\0') i=i-1;
else
while((avanexpr(algo[j]))&&(algo[j]!='!')) j++;
while(algo[j]!='\0') {
algo[i]=algo[j];
i++;
j++;
}
while(i<a) {
algo[i]='\0';
i++;
}
m=1;
}
i++;
if(m==1) i=0;
m=0;
}
i=0;
init(membre,strlen(membre));
// recompte les membres
free(membre);
membre=copymembre(algo,i);
i=i+strlen(membre);
if(membre[0]!='\0')
do
{
compte2++;
if(algo[i]=='&') i++;
init(membre,strlen(membre));
free(membre);
membre=copymembre(algo,i);
i=i+strlen(membre);
}while((i==0)||(membre[0]!='\0'));
init(membre,strlen(membre));
free(membre);
if(compte1!=compte2)
{
/* si les 2 nombres sont pas égaux alors un membre a disparu ce qui n'est pas correct.
ex: pour (a|b)&(c|d)&(d|e|f)&(!c|!d)&(a)&(!e|!f) l'algorithme de davis putmann va inclure (a) dans (a|b) donc (a|b) va disparaitre. ensuite il va trouver (a) comme membre seul et va le valider. aucune suppression dans la fonction maj. puis le programme ne va ni trouver de membre seul, ni de membre unique(présent dans un seul état (ex: que des (a) ou des (!a) dans l'expression)) donc va parcourrir un arbre. A ce moment là il va prendre la premiere lettre rencontrer (donc c si dessous vu que (a|b) a disparu) et va valider c. l'expression sera donc: (d|e|f)&(!d)&(!e|!f). arbre va se lancer recursivement et va faire la même chose sur la nouvelle expression. cette fois ci le premier membre est d, donc il va executer d. (d|e|f) disparait, mais dans maj il supprime (!d) vu qu'on a validé d, donc le programme doit normalement revenir en arriere est testé e désormais, mais quand j'essaie de faire free sur le nouvel algo qui est faux(dans maj apres avoir supprimer le !d) il me fait l'erreur */
printf("pas de solution\n" );
tmp=algo;
algo=calloc(6,sizeof(char));
init(algo,6);
strcpy(algo,"error" );
algo[5]='\0';
free(tmp); ==> seg fault
}
return algo;
}
char* arbre(char *algo,char reponse[],int *j)
{
// trouves une solution à l'algo entré, reponse[] contient les lettres déjà validé, j-1 pointe la derniere reponse trouvé. unsigned int i=0,e=0,k;
char *membre,*test;
// on copie le premier membre, sur l'exemple on copiera (c|d) la premiere fois
membre=copymembre(algo,i);
// on le supprime directement: (c|d) doit être impérativement validé.
algo=supprmembr(membre,algo);
// création d'un clone de algo.
test=calloc(strlen(algo)+1,sizeof(char));
init(test,strlen(algo)+1);
strcpy(test,algo);
while(membre[i]!='\0')
{
while(avanexpr(membre[i])) i++;
k=i;
if(membre[i]=='\0') break;
if((i>0)&&(test[i-1]=='!'))
{
// mise a jour de test avec le membre[i] (c'est à dire c a l'origine). si l'algo n'est plus valide test contiendra "erreur".
test=maj(test,membre[i],0);
}
if(algo[i-1]!='!')
{
// meme chose pour le cas ou c'est un a et non un !a
test=maj(test,membre[i],1);
}
if(strcmp(test,"error" )!=0)
// si test n'a pas rapporté d'erreur, on continue à parcourrir l'arbre.
{
printf("arbre\n" );
if((i>0)&&(membre[i-1]=='!'))
{
// on note la réponse.
reponse[*j]=membre[i-1];
reponse[*j+1]=membre[i];
*j=*j+2;
e=0;
if(test[0]=='\0') break;
i=i+strlen(membre);
free(membre);
// on relance arbre avec le nouvel algo.
test=arbre(test,reponse,j);
}
if(membre[i-1]!='!')
{
// meme chose pour a ...
reponse[*j]=membre[i];
*j=*j+1;
e=0;
if(test[0]=='\0') break;
i=i+strlen(membre);
init(membre,strlen(membre));
free(membre);
test=arbre(test,reponse,j);
}
// si le programme rapporte une erreur, on met e à 1 et on sort de la boucle.
on renvoit donc erreur au programme precedent.
if(strcmp(test,"error" )==0)
{
e=1;
break;
}
}
// si le string contient une erreur, on reinitialise algo, et on incremente i pour tester un autre membre. else
{
init(test,strlen(algo));
i=k+1;
strcpy(test,algo);
e=1;
}
}
if(e==1)
{
strcpy(test,"error" );
}
init(membre,strlen(membre));
free(membre);
return test;
}
|