EXpliquez comme cela c'est tout simple.
Je me lance. Il faudra que je fasse une fonction recursive.
Je ne passerais pas par une classe mais une simple fonction.
Je reviens vers toi pour te confirmer si j'ai réussi.
Merci pour ton aide
EXpliquez comme cela c'est tout simple.
Je me lance. Il faudra que je fasse une fonction recursive.
Je ne passerais pas par une classe mais une simple fonction.
Je reviens vers toi pour te confirmer si j'ai réussi.
Merci pour ton aide
Je te recommande la récursivité mais si ça te dérange tu peux t'en passer (toute solution récursive peut être réécrite avec une pile).
En revanche si tu décides de ne pas avoir de classe alors tu devras fournir jusqu'à quatre arguments à certains appels (texte, indice, arguments, booléen pour supprimer l'évaluation). Ça me semble un peu lourd mais bon à ta guise.
J'ai des petits soucis dans mon algo avec la récursivité.
En entrée de ma fonction j'aurais mon expression et un dictionnaire<int,bool> qui contient déjà le boolean permettant de savoir si le champ a été saisi ou non.
Par exemple :
j'ai 1,2,3,4 et 5 paramètres alors dans mon dictionnaire j'aurais ceci
<0,true> car saisie
<1,true> car saisie
<2,true> car saisie
<3,true> car saisie
<4,false> car non saisie
Bien evidement il est rempli en fonction des 5 paramètre.
En plus de ces 2 paramètre qui sont mon expression et le dictionnaire, j'aurais en plus un entier pour la position dans la règle et un autre entier pour la position dans le dico.
Mon algo change un peu mais j'emmêle les pinceaux au niveau de l'appel récursif à la fonction.
Voici un morceau de mon algo mais je pense qu'il n'est pas bon :
je ne suis pas bon et honnêtement je m'arrache un peu les cheveux. Je crois que cette ligne ne devrait pas etre la resultat &= groupValids[positionDico];
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 protected bool checkRule(string rules, Dictionary<int, bool> groupValids,int positionChaine,int positionDico) { int len = rules.Length; bool resultat = false; if (string.IsNullOrEmpty(rules)) return true; foreach (char rule in rules) { if (rule == '(') { // Je refais l'appel en incrementant la position dans la chaine resultat = checkRule(rules, groupValids, positionChaine + 1, positionDico); } int numRule; int.TryParse(rule.ToString(), out numRule); if (rule >= 1 && rule <= 9) { // Je recupere ma valeur du dictionnaire pour vérifier sa saisi resultat &= groupValids[positionDico]; positionDico++; // Je refais l'appel en incrementant la position dans la chaine et la position dans le dico resultat = checkRule(rules, groupValids, positionChaine + 1, positionDico); } // Il faut que je traite le & et le | ainsi que la parenthèse fermante if (rule == '&') resultat &= checkRule(rules, groupValids, positionChaine + 1, positionDico); if (rule == '|') resultat |= checkRule(rules, groupValids, positionChaine + 1, positionDico); } //return false; }
Pourrais tu m'aiguiller?
Merci
De plus, imaginons si un jour j'ai plus de 10 paramètres. Tout cela ne fonctionnera pas car je devrais à un moment données extraire 2 caractères et non plus juste un.
C'est le bordel
Pour commencer tu ne dois pas utiliser foreach.
D'abord parce que la façon dont tu interprètes un caractère dépend du précédent, par exemple "&" est valide après un chiffre mais pas après une parenthèse ouverte. Pour gérer ça avec un foreach il faudrait, pour chaque caractère reconnu, revérifier le caractère précédent. Il est plus simple et plus logique de ne pas avoir de foreach et d'avancer manuellement au fur et à mesure que tu reconnais les caractères : si tu viens de parser l'opérande gauche tu attends ensuite un opérateur et donc tu inséres seulement les instructions pour ce cas. Curieusement c'est ce que tu as fait à l'intérieur du foreach où l'on voit une séquence "opérande gauche - opérateur - opérande".
Ensuite parce que les appels récursifs font avancer le parsing. Chaque appel à checkRule doit prendre une position de départ de la sous-expression et retourner la position de fin de la sous-expression. Tu l'as compris mais pas mis en oeuvre puisque tu n'utilises pas ton "positionChaine". Pour ça tu peux soit passer positionChaine en "ref", soit ajouter un paramètre de sortie "out", soit renvoyer une paire "position de sortie / résultat". Au passage, parce que tu utilisais foreach plutôt que positionChaine, toutes tes sous-expressions recommençaient du début de la chaîne.
Commence donc par virer ce foreach et utiliser ton positionChaine, tu y verras plus clair.
DonQuiche > J'ai un peu de mal avec la recusivité. J'ai l'impression que mes conditions ne sont pas prises en compte.
Voici mon code:
Il me manque un truc et je ne trouve pas quoi.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 protected bool checkRule(string rules, Dictionary<int, bool> groupValids, int positionChaine, int positionDico) { int len = rules.Length; bool resultat = false; if (string.IsNullOrEmpty(rules)) return true; string rule = rules.Substring(positionChaine, 1); if (rule == "(") { // Je refais l'appel en incrementant la position dans la chaine resultat = checkRule(rules, groupValids, positionChaine + 1, positionDico); } int numRule; int.TryParse(rule, out numRule); if (numRule >= 1 && numRule <= 9) { // Je recupere ma valeur du dictionnaire pour vérifier sa saisi resultat &= groupValids[positionDico]; positionDico++; // Je refais l'appel en incrementant la position dans la chaine et la position dans le dico resultat = checkRule(rules, groupValids, positionChaine + 1, positionDico); } // Il faut que je traite le & et le | ainsi que la parenthèse fermante if (rule == "&") resultat &= checkRule(rules, groupValids, positionChaine + 1, positionDico); if (rule == "|") resultat |= checkRule(rules, groupValids, positionChaine + 1, positionDico); //Tant que l'on est pas à la fin on continue d'avancer if (rule == ")" && positionChaine < rules.Length) resultat &= checkRule(rules, groupValids, positionChaine + 1, positionDico); return resultat; }
* Ton principal problème ici est que positionChaine n'est pas modifiée dans l'appel parent : si tu as une opérande de 5 caractères (par exemple (a|b)) alors positionChaine doit être augmentée de 5 caractères au retour. Une solution pour ça est de passer "positionChaine" en "ref" (mot-clé c#) ou d'en faire une variable d'instance. Note aussi qu'avec "ref" tu dois faire l'addition avant de faire l'appel.
* Ta variable "rule" n'est actuellement jamais modifiée. Tu dois la recalculer chaque fois que tu modifies positionChaine, sans quoi c'est toujours le premier caraactère. Au passage pour son type pas besoin d'une chaîne alors qu'un seul caractère suffirait. Tu pourrais alors utiliser rules[positionChaine] plutôt que ce Substring.
* Il ne peut pas y avoir de nombre après une parenthèse ouverte. L'opérande gauche est soit un nombre, soit une opération entre parenthèses, pas les deux à la suite. Ton code devrait refléter explicitement ça avec un "if/else" plutôt que de s'appuyer implicitement sur la valeur par défaut pour numRule après TryParse. C'est typiquement le genre de bidouille qui obscurcit le code, complexifie sa lecteur et se transforme en niche à bogue. Écris ton code pour des êtres humains.
* Dans le même esprit ta gestion de la parenthèse fermée est laxiste: actuellement il autorise des parenthèses fermées en trop. Ça peut encore passer mais bon...
* Si la récursivité te dérange, passe t-en : utilise une boucle while couplée ) une pile (Stack<bool>) pour stocker les résultats des opérandes gauches.
Merci pour ta réponse.
J'aimerais continuer à utiliser la récursivité car c'est un nouveau concept pour moi et j'aimerais bien le gérer à l'avenir.
Ensuite tu dis cela:
Ma position chaine est augmenté de 1 à chaque appel. Quand je debug je vois que le caractère change.* Ton principal problème ici est que positionChaine n'est pas modifiée dans l'appel parent : si tu as une opérande de 5 caractères (par exemple (a|b)) alors positionChaine doit être augmentée de 5 caractères au retour. Une solution pour ça est de passer "positionChaine" en "ref" (mot-clé c#) ou d'en faire une variable d'instance. Note aussi qu'avec "ref" tu dois faire l'addition avant de faire l'appel.
Pourquoi devrait il être augmenté de 5? Je devrais les traiter un par un.
A moins que tu veuilles que je travaille expression par expression, c'est à dire que je récupère toute règle en parenthèse que j'evalue et ensuite je passe à la suivante.
Si c'est cela, comment traiter ceci ((a&b) | (c&d)). Il faut que j'analyse le |à un moment donné.
Tu as raison j'utiliserais ceci à l'avenir rules[positionChaine]* Ta variable "rule" n'est actuellement jamais modifiée. Tu dois la recalculer chaque fois que tu modifies positionChaine, sans quoi c'est toujours le premier caraactère. Au passage pour son type pas besoin d'une chaîne alors qu'un seul caractère suffirait. Tu pourrais alors utiliser rules[positionChaine] plutôt que ce Substring.
je ne saisi pas tout. Désole
Ce que tu vois ce sont les variables dans l'appel enfant : ces variables n'ont pas les mêmes valeurs dans l'appel parent. A chaque appel récursif tu crées de nouvelles variables ayant le même nom. Tu peux le vérifier en mode debug : si tu double-cliques sur l'appel parent dans la pile des appels, tu verras que VS t'affiche alors d'autres valeurs pour ces variables et surligne une autre position d'exécution.
Or, donc, il ne te faut pas des pelletées de "positionChaine" ayant le même nom et des valeurs différentes mais au contraire une seule valeur commune et partagée. Tu peux soit utiliser une variable d'instance, ou alors passer ta variable initiale en "ref", auquel cas tu auras des pelletées de références pointant toutes vers une variable unique.
De 5 parce que "(a|b)" mesure cinq caractères. Ton algorithme va incrémenter cinq fois de un, à chaque fois qu'il traitera un nouveau caractère. Ca sera fait automatiquement quand tu passeras ta variable par "ref" ou en instance. Tu n'as pas à changer ton algorithme, tu as déjà un "+1" après chaque caractère.Pourquoi devrait il être augmenté de 5? Je devrais les traiter un par un.
C'est tout à fait normal et tu n'as pas à t'en excuser.je ne saisi pas tout. Désole
Il faut bien apprendre un jour et par ailleurs tu ne ménages pas ta peine.
J'ai compris pour le ref. Cela signifie que le changement de positionChaine sera prise en compte quelque soit le sous niveau (enfant).
Par contre, je m'embrouille encore avec cet algo.
Finalement si je rencontre '(' alors j'incrément positionChaine et je fais appel à checkRule avec positionChaine en ref.
Par contre si je rencontre une opérande de 1 à 9. Dois je incrémenter positionChaine? Je pense que oui sinon on n'avance pas. j'augmente aussi positionDico.
je dois faire quoi exactement je fais un if sur quel valeur?
Code : Sélectionner tout - Visualiser dans une fenêtre à part * Il ne peut pas y avoir de nombre après une parenthèse ouverte. L'opérande gauche est soit un nombre, soit une opération entre parenthèses, pas les deux à la suite. Ton code devrait refléter explicitement ça avec un "if/else" plutôt que de s'appuyer implicitement sur la valeur par défaut pour numRule après TryParse. C'est typiquement le genre de bidouille qui obscurcit le code, complexifie sa lecteur et se transforme en niche à bogue. Écris ton code pour des êtres humains.
Il faut savoir que la manière dont on construit l'algo, a terme il ne répondra pas à toutes les exigences mais cela on en discutera à la fin si tu veux bien.
Petit exemple: si j'ai plus de 9 paramètres, mes règles risque de ressembler à ceci ((9&10)|(11&12))
Je pense que tu as compris ou je veux en venir.
* Le test doit porter sur "rule == '('". En gros ton algo doit faire: si parenthèse alors parser sous-expression entre parenthèses, sinon parser nombre. Ca revient simplement à ajouter un bloc else à ton code et y regrouper toute la gestion des nombres.
* Tu dois incrémenter positionChaine à chaque caractère traité. Donc en rencontrant un chiffre tu dois effectivement incrémenter.
* Pour gérer les nombres à plusieurs chiffres voici deux solutions:
a) Ce que moi j'avais fait : une boucle while parcourt tous les chiffres pour les compter (ou trouver l'index du dernier chiffre ou du premier non-chiffre, il y a plusieurs variantes de l'algo). Puis on utilise cette info pour extraire la sous-chaîne du nombre (via Substring) et on passe celle-ci à int.Parse.
b) On oublie int.Parse et TryParse et on parse manuellement au fil de l'eau : on commence avec une variable nombre = 0 et à chaque chiffre on fait nombre = nombre * 10 + chiffre.
Je pense me rapprocher le plus de ce que tu me dis. Ce qui est bien, est que je comprend déjà mieux le code et comment ça fonctionne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 protected bool checkRule(string rules, Dictionary<int, bool> groupValids,ref int positionChaine, int positionDico) { int len = rules.Length; bool resultat = false; if (string.IsNullOrEmpty(rules)) return true; if (rules[positionChaine] == '(') { positionChaine++; // Je refais l'appel en incrementant la position dans la chaine resultat = checkRule(rules, groupValids, ref positionChaine, positionDico); } else { bool ischiffre = true; int chiffre; int positionDeb = positionChaine; while (ischiffre) { if (int.TryParse(rules[positionChaine].ToString(), out chiffre)) positionChaine++; else ischiffre = false; } string operande = rules.Substring(positionDeb, positionChaine - positionDeb); if (operande.Length > 0) { // Je recupere ma valeur du dictionnaire pour vérifier sa saisi resultat = groupValids[positionDico]; positionDico++; positionChaine++; // Je refais l'appel en incrementant la position dans la chaine et la position dans le dico resultat = checkRule(rules, groupValids, ref positionChaine, positionDico); } } // Il faut que je traite le & et le | ainsi que la parenthèse fermante if (rules[positionChaine] == '&') { positionChaine++; resultat &= checkRule(rules, groupValids, ref positionChaine, positionDico); } if (rules[positionChaine] == '|') { positionChaine++; resultat |= checkRule(rules, groupValids, ref positionChaine, positionDico); } //Tant que l'on est pas à la fin on continue d'avancer if (rules[positionChaine] == ')' && positionChaine < rules.Length) { positionChaine++; resultat &= checkRule(rules, groupValids, ref positionChaine, positionDico); } return resultat; }
Il me reste encore des cas à gérer, comme la comparaison avec une autre parenthèse.
Qu'en penses tu ?
Oui, tu touches le bon bout, félicitations.
Voici mes remarques et suggestions.
* Les bogues:
a) Tu n'utilises pas la valeur de "operande" dans le cas où l'opérande gauche est un nombre. A la place tu utilises "positionDico" dont je ne vois pas à quoi elle sert.
b) Tu ne testes pas toujours que index est une position valide. Tu l'as fait seulement à la fin (parenthèses fermantes) et incorrectement (le test de position doit être fait avant le test du caractère).
* Tu dois définir comment ton algorithme est supposé se comporter avec les chaînes incorrectes. Doit-il être tolérant ou au contraire lever une exception à la moindre erreur ? Est-ce le cas actuellement ? Tes tests couvrent-ils ces cas ?
* La boucle de recherche du dernier nombre est vraiment sale, tu peux l'améliorer et la raccourcir. Voici quelques conseils en général pour améliorer la lisibilité d'un code. Libre à toi de picorer ce que tu veux.
a) Éviter les abréviations : "positionDeb" n'est pas explicite pour un développeur qui découvre ta fonction sans connaître le problème. Ca ne vaut pas l'économie de deux caractères (par contre "position" suffirait peut-être à remplacer "positionChaine" vu le contexte). Si tu veux être concis mieux vaut "début".
b) Déclarer les variables d'une fonction au dernier moment : "chiffre" peut être déclaré dans la boucle.
c) Utiliser des sous-fonctions. D'abord cela hiérarchise les niveaux de lecture et de compréhension (niveau le plus haut : l'algorithme "si parenthèse parser sous-expression sinon parser nombre", niveau le plus bas les détails "incrémenter telle variable, lire telle variable, etc"). Ensuite des noms bien choisis auto-documentent le code et remplacent avantageusement les commentaires. Parmi les pistes possibles ici : EstUnChiffre, CompterChiffres, TrouverFinDuNombre, LireNombre, etc.
d) Savoir quand utiliser les "clauses défensives" : ce sont des branchements conditionnels du type "si telle condition alors quitter", ou quitter peut soit être un "return" pour quitter la fonction ou un "break" pour quitter une boucle. Les clauses défensives sont utilisées pour gérer les cas exceptionnels, les conditions aux bords ou, souvent pour les boucles, les conditions de fin. Tu en as justement utilisé une pour le cas où "rules" est vide et ça peut être une piste pour transformer la boucle de recherche de fin du nombre.
PS : Robert Martin explique très bien tout ça dans "Coder Proprement", un excellent ouvrage que j'aurais aimé lire dix ans plus tôt que je ne l'ai lu (ça m'aurait évité de passer dix ans à à découvrir tout ça par moi-même dans la douleur).
Voici mon code nettoyer :
Cependant, lorsque je teste je plante car je sors des limites du tableau (rules). Avec la recursivité, je m'y perds dans le debug mais j'essai de m'accrocher pour trouver le problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 protected bool checkRule(string rules, Dictionary<int?, bool> groupValids,ref int position) { int len = rules.Length; bool resultat = false; if (string.IsNullOrEmpty(rules)) return true; if (position < rules.Length) { if (rules[position] == '(') { // Je refais l'appel en incrementant la position dans la chaine position++; resultat = checkRule(rules, groupValids, ref position); } else { // On recupere le nombre qu'il soit sur 1 ou 2 caractères string operande = LireNombre(rules, ref position); // On vérifie que l'on a recupéré un nombre if (operande.Length > 0) { // Je recupere ma valeur du dictionnaire pour vérifier sa saisi resultat = groupValids[int.Parse(operande)]; // Je refais l'appel en incrementant la position dans la chaine position++; resultat = checkRule(rules, groupValids, ref position); } } // Il faut que je traite le & et le | ainsi que la parenthèse fermante if (rules[position] == '&') { position++; resultat &= checkRule(rules, groupValids, ref position); } if (rules[position] == '|') { position++; resultat |= checkRule(rules, groupValids, ref position); } //Tant que l'on est pas à la fin on continue d'avancer if (rules[position] == ')') { position++; resultat &= checkRule(rules, groupValids, ref position); } } return resultat; }
De plus, si je tombe en erreur dans ma rules alors je renvoi false et non lever une exception.
Pour finir, comment je n'arrive pas à comprendre comment garder mon résultat pour le comparer au suivant.
Je m'explique si j'ai cette règle (1&2)|(3&4) et que j'ai tout saisi alors
résultat devrait être égale à :
- True lors de la 1ere operande
- True & True lors de la 2eme operande qui donnera True
- ensuite j'arrive au | et la je pèche car je dois garder resultat à True de mon ancien passage et je dois ensuite comparer 3&4 pour pouvoir le vérifier avec le |.
A Revoir car je ne suis pas
Concernant test de position, tu vérifies au début mais entretemps tu as modifié cette position et elle peut donc être à nouveau hors-tableau. Tu dois donc ajouter davantage de vérifications, soit après chaque incrémentation (ou après chaque incrémentation possible), soit avant chaque lecture de caractère. Par ailleurs tu t'y es pris d'une façon assez laide dans ton dernier code, mieux vaudrait des clauses défensives (si position invalide alors renvoyer résultat) ou un ET conditionnel (si position valide && caractère == '(' alors).
Concernant l'ordre d'évaluation, c'est toujours au fil de l'eau:Les niveaux représentent la profondeur de la pile d'appel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 ( True & True ) | ( True & True )
- On est descendu après chaque parenthèse ouverte
- On est descendu après chaque opérateur booléen (l'opérande droite est toujours une sous-expression)
PS : Ce n'est qu'un conseil d'ordre général mais sur le long terme tu devrais chercher à avoir moins de commentaires et plus de sous-fonctions dont les noms font office de commentaire.
PPS : Attention il est possible avec ton code d'avoir des parenthèses ouvertes mais jamais fermées ou, réciproquement, des parenthèses fermées sans parenthèses ouvertes au préalable. Si c'est voulu, très bien.
Je fais mon test de position dans tous les cas et tu avais raison à ce sujet. Normal que je soit en erreur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 protected bool checkRule(string rules, Dictionary<int?, bool> groupValids,ref int position) { int len = rules.Length; bool resultat = false; if (string.IsNullOrEmpty(rules)) return true; if (PositionValide(rules,position)) { if (PositionValide(rules,position) && rules[position] == '(') { position++; resultat = checkRule(rules, groupValids, ref position); } else { string operande = LireNombre(rules, ref position); if (operande.Length > 0) { resultat = groupValids[int.Parse(operande)]; position++; resultat = checkRule(rules, groupValids, ref position); } } if (PositionValide(rules,position) && rules[position] == '&') { position++; resultat &= checkRule(rules, groupValids, ref position); } if (PositionValide(rules,position) && rules[position] == '|') { position++; resultat |= checkRule(rules, groupValids, ref position); } if (PositionValide(rules,position) && rules[position] == ')') { position++; resultat &= checkRule(rules, groupValids, ref position); } } return resultat; } /// <summary> /// Lecture de la règle pour récupérer le prochain nombre qu'il soit sur 1 ou 2 caractères /// </summary> /// <param name="rules"></param> /// <param name="position"></param> /// <returns></returns> protected string LireNombre(string rules, ref int position) { int debut = position; while (position < rules.Length) { if (EstUnChiffre(rules[position].ToString())) position++; else break; } return rules.Substring(debut, position - debut); } /// <summary> /// Vérifie que le champ valeur est un entier /// </summary> /// <param name="valeur"></param> /// <returns></returns> protected bool EstUnChiffre(string valeur) { int chiffre; return int.TryParse(valeur, out chiffre); } /// <summary> /// Vérifie que la position est inférieur à la taille de la règle /// </summary> /// <param name="valeur"></param> /// <returns></returns> protected bool PositionValide(string rules, int position) { return (position < rules.Length? true: false); }
Je devrais avoir le même nombre de parenthèses ouvertes que de fermées. C'est une obligation.PPS : Attention il est possible avec ton code d'avoir des parenthèses ouvertes mais jamais fermées ou, réciproquement, des parenthèses fermées sans parenthèses ouvertes au préalable. Si c'est voulu, très bien.
Mon script ne fonctionne pas comme voulu car il renvoit false quand j'ai ceci (True&True)|(false&false) ==> je devrais avoir true
Il y a au moins un bogue dans ta gestion des nombres : tu incrémentes à nouveau position alors que LireNombre devrait déjà t'avoir positionné correctement. Pour le reste il faut y aller au débogage pas à pas.
Oui mais une erreur est vite arrivée, d'où l'intérêt d'avoir des vérifications qui te sautent au visage plutôt que des erreurs silencieuses et difficiles à trouver. Dans le même genre si j'étais toi j'ajouterais une condition pour vérifier que le premier appel se termine bien à la fin de la chaîne pour s'assurer que tout a été parsé.Je devrais avoir le même nombre de parenthèses ouvertes que de fermées. C'est une obligation.
J'ai modifié mon code et retirer le position++ à cette endroit:
Franchement je n'arrive pas à trouver où est le problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 if (operande.Length > 0) { resultat = groupValids[int.Parse(operande)]; //position++; resultat = checkRule(rules, groupValids, ref position); }
J'ai toujours False dans tous les cas.
Tu veux dire quoi par là ? Je ne suis pas car je fais déjà mon test sur la position < rules.length.Dans le même genre si j'étais toi j'ajouterais une condition pour vérifier que le premier appel se termine bien à la fin de la chaîne pour s'assurer que tout a été parsé.
Au passage tu pourrais aussi virer la vérification de la longueur de l'opérande: de toute façon elle doit être supérieure à zéro. Si ce n'était pas le cas cela voudrait dire qu'il y a une erreur quelque part, donc autant avoir cette erreur le plus tôt possible (pllus une erreur est détectée tôt, plus le problème est facile à déboguer).
Tel quel je ne vois aucun problème. Prends le débogueur et avance pas-à-pas (F10/F11) pour savoir à quel moment l'erreur apparaît. C'est l'occasion d'acquérir ou de perfectionner des compétences qui te seront extrêmement utiles et vont te faire gagner du temps.Franchement je n'arrive pas à trouver où est le problème.
J'ai toujours False dans tous les cas.
Ce que je veux dire c'est qu'une fois que le parsing est terminé, position devrait être égal à rules.Length. Vérifier cela peut être une bonne idée, à nouveau pour réduire le risque d'erreur silencieuse.Tu veux dire quoi par là ? Je ne suis pas car je fais déjà mon test sur la position < rules.length.
Mon script n'est pas bon. Je suis d'accord avec toi qu'il parse ma rues mais le probleme est que si je rencontre cette rules (1&2)|(3&4).
Je devrais récupérer false alors qu'il me renvoi car il fait
(True&True)|(True&True) ==> TRUE
Aurais tu une idée de comment tourner mon algo pour qu'il vérifie cela?
Merci
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager