lezj
Messages postés66Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 juillet 2013
-
11 févr. 2010 à 04:14
lezj
Messages postés66Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 juillet 2013
-
11 févr. 2010 à 16:54
bonjour(ou bonsoir)
je viens demander l'aide de toutes bonnes volontés.
j'ai une calculatrice à faire ne vb.net(mode console) et pour l'instant je pensais avoir réussi mais je me suis rendu compte de quelques beugues:
enfait, le programme recoit une opération sous forme de chaine de caractères(ex:12+8-10*3/5) et revoie le résultat.
les problèmes sont les suivants:
1- le programme beugue lorsque les multiplications et les divisions se succèdent
2- je dois également gérer les parenthèses et j'avoue que je ne sais pas par où commencer.
merci à toutes les personnes qui voudront bien m'aider.
Public Sub initpile(ByVal p() As String, ByVal n As Integer, ByVal sommet As Integer)
sommet = -1
End Sub
Public Function pilevide(ByVal p() As String, ByVal n As Integer, ByRef sommet As Integer) As Boolean
If (sommet = -1) Then
pilevide = True
Else
pilevide = False
End If
Return (pilevide)
End Function
Public Sub extraire(ByVal ch As String, ByVal n As Integer, ByVal t() As String, ByRef k As Integer)
Dim i, j, l As Integer
Dim nbr As String
j = 0
For i = 0 To ch.Length - 1
nbr = ""
If ((est_operateur(ch.Substring(i, 1)) = True)) Then
For l = j To i - 1
nbr = nbr & ch.Substring(l, 1)
Next
t(k) = nbr
k += 1
t(k) = ch.Substring(i, 1)
k = k + 1
j = i + 1
End If
If (i = ch.Length - 1) Then
For l = j To i
nbr = nbr & ch.Substring(l, 1)
Next
t(k) = nbr
End If
Next
End Sub
Public Sub empiler(ByVal val As String, ByVal n As Integer, ByRef p() As String, ByRef sommet As Integer)
If (pilevide(p, n, sommet) = True) Then
sommet = 0
p(sommet) = val
Else
If (sommet = n) Then
WriteLine("La pile est pleine!")
Else
sommet += 1
p(sommet) = val
End If
End If
End Sub
Public Sub depiler(ByRef p() As String, ByVal n As Integer, ByRef sommet As Integer, ByRef val As String)
If (pilevide(p, n, sommet) = True) Then
WriteLine("La pile est vide!")
Else
val = p(sommet)
p(sommet) = Nothing
'If (sommet = 0) Then
'initpile(p, n, sommet)
'Else
sommet -= 1
'End If
End If
End Sub
Public Function priorite(ByVal operateur As String, ByVal sommet As Integer, ByVal p() As String, ByVal n As Integer) As Boolean
If (((operateur "*") Or (operateur "/")) And ((p(sommet) = "+") Or (p(sommet) = "-"))) Then
priorite = True
ElseIf (((operateur "+") Or (operateur "-")) And ((p(sommet) = "+") Or (p(sommet) = "-"))) Then
priorite = True
ElseIf (((operateur "*") Or (operateur "/")) And ((p(sommet) = "*") Or (p(sommet) = "/"))) Then
priorite = True
Else
priorite = False
End If
Return (priorite)
End Function
Public Function est_operateur(ByVal operateur As String) As Boolean
If ((operateur "*") Or (operateur "/") Or (operateur = "+") Or (operateur = "-")) Then
est_operateur = True
Else
est_operateur = False
End If
Return (est_operateur)
End Function
Public Sub calculer(ByVal t() As String, ByVal k As Integer, ByVal n As Integer, ByVal total As String, ByVal nb() As String, ByVal op() As String, ByVal s1 As Integer, ByVal s2 As Integer)
Dim i As Integer
Dim res1, res2, res3 As String
Dim totalint As Integer
res1 = ""
res2 = ""
res3 = ""
For i = k To 0 Step -1
If (est_operateur(t(i)) = True) Then
If (pilevide(op, n, s2) = True) Then
empiler(t(i), n, op, s2)
Else
If ((priorite(t(i), s2, op, n) False) And (pilevide(op, n, s2) False)) Then
depiler(op, n, s2, res1)
If (res1 = "+") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) + Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s2)
If (pilevide(op, n, s2) = True) Then
empiler(t(i), n, op, s2)
' Exit For
End If
End If
If (res1 = "-") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) - Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
If (pilevide(op, n, s2) = True) Then
empiler(t(i), n, op, s2)
End If
End If
If (res1 = "*") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) * Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
If (pilevide(op, n, s2) = True) Then
empiler(t(i), n, op, s2)
'Exit For
End If
End If
If (res1 = "/") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
If (Val(res3) = 0) Then
WriteLine("Erreur! Division par 0 impossible.")
' Exit Sub
Else
totalint = Val(res2) / Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
If (pilevide(op, n, s2) = True) Then
empiler(t(i), n, op, s2)
' Exit For
End If
End If
End If
Else
empiler(t(i), n, op, s2)
End If
'empiler(t(i), n, op, s2)
End If
Else
empiler(t(i), n, nb, s1)
End If
Next
Do
depiler(op, n, s2, res1)
If (res1 = "*") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) * Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
End If
If (res1 = "/") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
If (Val(res3) = 0) Then
WriteLine("Erreur! Division par 0 impossible.")
Exit Do
Else
totalint = Val(res2) / Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
End If
End If
If (res1 = "+") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) + Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
End If
If (res1 = "-") Then
depiler(nb, n, s1, res2)
depiler(nb, n, s1, res3)
totalint = Val(res2) - Val(res3)
total = totalint.ToString()
empiler(total, n, nb, s1)
End If
Loop Until (pilevide(op, n, s2) = True)
WriteLine(total)
End Sub
Sub Main()
Const n As Integer = 20
Dim k As Integer = 0
Dim t(n) As String
Dim op(n), nb(n) As String
Dim total As Integer
Dim s1, s2 As Integer
Dim ch As String
s1 = -1
s2 = -1
initpile(nb, n, s1)
initpile(op, n, s2)
WriteLine("Entrez l'expression a calculer: ")
ch = ReadLine()
extraire(ch, n, t, k)
calculer(t, k, n, total, nb, op, s1, s2)
ReadKey()
End Sub
End Module
----------------------------------------------
Lez-J
mdevaux62
Messages postés111Date d'inscriptiondimanche 24 décembre 2000StatutMembreDernière intervention17 novembre 20127 11 févr. 2010 à 10:45
Bonjour,
Il y a pas mal de temps, j'avais fait ça en VB6.
La fonction gère les parenthèses par récursivité et traite les 4 opérations avec les priorités.
La fonction recherche les paires de parenthèses et s'autoappelle pour en résoudre le contenu.
Quand l'expression envoyée ne contient plus de parenthèses elle est évaluée avec respect des priorités.
Pour expliquer : soit ((A+B/C)*D)-E/2
1) Une paire de parenthèses est détectée avec pour contenu (A+B/C)*D. La fonction s'autoappelle (récursivité) pour résoudre l'expression.
2) Mais dans cette expression, il y a une autre paire de parenthèses (A+B/C). Là encore la fonction s'autoappelle pour résoudre l'expression A+B/C
3) Plus de parenthèses dans l'expression. On traite en priorité les multiplications et les divisions puis les additions et les soustractions.
4) Et voilà !
Le code :
Pour rendre le code compatible avec .Net je n'ai fait que faire appel à la bibliothèque microsoft.visualbasic ce qui n'est pas trop élégant. Je t'encourage donc à le récrire de façon plus propre.
Bon courage.
MD
Public Function CalculOperation(ByVal chaine As String) As String
Dim i As Integer
Dim chrA As String
Dim chrC As String
Dim extrait As String
Dim calcul As String
Dim parenthG As Integer
Dim parenthD As Integer
Dim addit As Integer
Dim soust As Integer
Dim multp As Integer
Dim divis As Integer
Dim signe As Integer
Dim gauche As Integer
Dim droite As Integer
Dim sign1 As Integer
Dim sign2 As Integer
Dim element1 As String
Dim element2 As String
Dim chrSigne As String
Dim signe1 As String
Dim signe2 As String
Dim nombre1 As String
Dim nombre2 As String
Dim resultat As String
Dim calc As Double
Dim calc1 As Double
Dim calc2 As Double
chaine = chaine.Replace(" ", "")
chaine = chaine.Replace(",", ".")
chaine = chaine.Replace("*", "x")
chaine = chaine.Replace("X", "x")
chaine = chaine.Replace("/", ":")
parenthG = 0
parenthD = 0
If Len(chaine) Then
For i = 1 To Len(chaine)
chrA = Mid(chaine, i, 1)
If chrA "(" Then parenthG parenthG + 1
If chrA ")" Then parenthD parenthD + 1
If InStr(1, "0123456789.+-x:()", chrA) 0 Then i Len(chaine) : chaine = "?"
Next i
If parenthG <> parenthD Then chaine = "?"
'*** Traiter les parenthèses
Do While InStr(1, chaine, "(") > 0
gauche = InStr(1, chaine, "(")
droite = 0
parenthG = 0
parenthD = 0
For i = gauche + 1 To Len(chaine)
chrA = Mid(chaine, i, 1)
If chrA "(" Then parenthG parenthG + 1
If chrA ")" Then If parenthG parenthD Then droite = i : i = Len(chaine) Else parenthD = parenthD + 1
Next i
If parenthD parenthG + 1 Then chaine "?"
If gauche > 1 Then If InStr(1, "0123456789", Mid(chaine, gauche - 1, 1)) Then chaine = "?"
If droite < Len(chaine) Then If InStr(1, "0123456789", Mid(chaine, droite + 1, 1)) Then chaine = "?"
If chaine <> "?" Then
extrait = Mid(chaine, gauche + 1, droite - gauche - 1)
extrait = CalculOperation(extrait) 'Récursivité !
chaine = Microsoft.VisualBasic.Left(chaine, gauche - 1) + extrait + Microsoft.VisualBasic.Right(chaine, Len(chaine) - droite)
End If
Loop
'*** Traiter les multpiplications et les divisions
chaine = chaine.Replace(",", ".")
calcul = chaine
If InStr(1, "0123456789.", Microsoft.VisualBasic.Right(calcul, 1)) 0 Then chaine "?"
Do While (InStr(1, calcul, "x") > 0 Or InStr(1, calcul, ":") > 0) And InStr(1, chaine, "?") = 0
divis InStr(1, calcul, ":") : If divis Then chrSigne ":" : signe = divis
multp InStr(1, calcul, "x") : If divis 0 Then chrSigne = "x" : signe = multp
element1 "" : gauche 1
element2 "" : droite Len(calcul)
For i = signe + 1 To Len(calcul)
chrC = Mid(calcul, i, 1)
If InStr(1, "0123456789", chrC) Then element2 = element2 + chrC
If InStr(1, ".", chrC) Then If InStr(1, ".", element2) Then i Len(calcul) : chaine "?" Else element2 = element2 + chrC
If InStr(1, "x:", chrC) Then If Len(element2) > 0 Then droite i - 1 : i Len(calcul) Else i = Len(calcul) : chaine = "?"
If InStr(1, "+-", chrC) Then If Len(element2) 0 Then element2 chrC Else If InStr(1, "0123456789.", Microsoft.VisualBasic.Right(element2, 1)) Then droite = i - 1 : i = Len(calcul) Else chaine = "?" : i = Len(calcul)
Next i
If signe > 1 Then
For i = signe - 1 To 1 Step -1
chrC = Mid(calcul, i, 1)
If InStr(1, "0123456789", chrC) Then element1 = chrC + element1
If InStr(1, ".", chrC) Then If InStr(1, ".", element1) Then i 1 : chaine "?" Else element1 = chrC + element1
If InStr(1, "x:", chrC) Then If Len(element1) > 0 Then gauche i + 1 : i 1 Else i = 1 : chaine = "?"
If InStr(1, "+-", chrC) Then If Len(element1) > 0 Then gauche i : i 1 : element1 = chrC + element1 Else i = 1 : chaine = "?"
Next i
If InStr(1, "+-", Microsoft.VisualBasic.Left(element1, 1)) 0 Then element1 "+" + element1
If InStr(1, "+-", Microsoft.VisualBasic.Left(element2, 1)) 0 Then element2 "+" + element2
signe1 Microsoft.VisualBasic.Left(element1, 1) : nombre1 Microsoft.VisualBasic.Right(element1, Len(element1) - 1) : calc1 = Val(nombre1)
signe2 Microsoft.VisualBasic.Left(element2, 1) : nombre2 Microsoft.VisualBasic.Right(element2, Len(element2) - 1) : calc2 = Val(nombre2)
'DEFSTR LONG
If signe1 signe2 Then chrSigne "+" Else chrSigne = "-"
If signe = multp Then
calc = calc1 * calc2
Else
If calc2 0 Then chaine "?" Else calc = calc1 / calc2
End If
resultat Str(calc) : If gauche 1 And chrSigne = "+" Then chrSigne = ""
resultat = chrSigne + Microsoft.VisualBasic.Right(resultat, Len(resultat) - 1)
'DEFSTR WORD
calcul = Microsoft.VisualBasic.Left(calcul, gauche - 1) + resultat + Microsoft.VisualBasic.Right(calcul, Len(calcul) - droite)
Else
chaine = "?"
End If
Loop
'*** Traiter les additions et les soustractions
If InStr(1, "0123456789.", Microsoft.VisualBasic.Right(calcul, 1)) 0 Then chaine "?"
sign1 = InStr(1, "+-", Mid(calcul, 1, 1))
sign2 = InStr(1, "+-", Mid(calcul, 2, 1))
If sign1 > 0 And sign2 > 0 Then signe sign1 <> sign2 : calcul Mid("-+", 2 + signe, 1) + Microsoft.VisualBasic.Right(calcul, Len(calcul) - 2)
Do While (InStr(2, calcul, "+") > 0 Or InStr(2, calcul, "-") > 0) And InStr(1, chaine, "?") = 0
soust InStr(2, calcul, "-") : If soust > 1 Then chrSigne "-" : signe = soust
addit InStr(2, calcul, "+") : If addit > 1 Then If soust > 1 And soust < addit Then addit 0 Else soust = 0 : chrSigne = "+" : signe = addit
element1 "" : gauche 1
element2 "" : droite Len(calcul)
For i = signe + 1 To Len(calcul)
chrC = Mid(calcul, i, 1)
If InStr(1, "0123456789", chrC) Then element2 = element2 + chrC
If InStr(1, ".", chrC) Then If InStr(1, ".", element2) Then i Len(calcul) : chaine "?" Else element2 = element2 + chrC
If InStr(1, "+-", chrC) Then If Len(element2) 0 Then element2 chrC Else If InStr(1, "0123456789.", Microsoft.VisualBasic.Right(element2, 1)) Then droite = i - 1 : i = Len(calcul) Else chaine = "?" : i = Len(calcul)
Next i
For i = signe - 1 To 1 Step -1
chrC = Mid(calcul, i, 1)
If InStr(1, "0123456789", chrC) Then element1 = chrC + element1
If InStr(1, ".", chrC) Then If InStr(1, ".", element1) Then i 1 : chaine "?" Else element1 = chrC + element1
If InStr(1, "+-", chrC) Then If Len(element1) > 0 Then gauche i : i 1 : element1 = chrC + element1 Else i = 1 : chaine = "?"
Next i
If InStr(1, "+-", Microsoft.VisualBasic.Left(element1, 1)) 0 Then element1 "+" + element1
If InStr(1, "+-", Microsoft.VisualBasic.Left(element2, 1)) 0 Then element2 "+" + element2
calc1 = Val(element1)
calc2 = Val(element2)
'DEFSTR LONG
If signe soust Then calc calc1 - calc2 Else calc = calc1 + calc2
resultat = Str(calc)
'DEFSTR WORD
calcul = Microsoft.VisualBasic.Left(calcul, gauche - 1) + resultat + Microsoft.VisualBasic.Right(calcul, Len(calcul) - droite)
Loop
End If
If InStr(1, chaine, "?") Then
chaine = "?"
Else
chaine = calcul
chaine = chaine.Replace(".", ",")
chaine = chaine.Replace(" ", "")
If Microsoft.VisualBasic.Left(chaine, 1) "," Then chaine "0" + chaine
End If
Return chaine
End Function
lezj
Messages postés66Date d'inscriptionsamedi 14 août 2004StatutMembreDernière intervention 5 juillet 2013 11 févr. 2010 à 16:54
salut mdevaux62
je te remercie non seulement pour ton temps, pour ta bonne volonté et SURTOUT PARCE QUE TON CODE FONCTIONNE!tu viens de me sauver la mise, je te remercie beaucoup.
A charge de revanche!