Aide pour calculatrice en vb.net

Résolu
lezj Messages postés 66 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 juillet 2013 - 11 févr. 2010 à 04:14
lezj Messages postés 66 Date d'inscription samedi 14 août 2004 Statut Membre Derniè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.

voici mon code:
----------------------------------------------
Imports System.Console
Module Module1

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

2 réponses

mdevaux62 Messages postés 111 Date d'inscription dimanche 24 décembre 2000 Statut Membre Dernière intervention 17 novembre 2012 7
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
2
lezj Messages postés 66 Date d'inscription samedi 14 août 2004 Statut Membre Derniè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!


Lez-J
0
Rejoignez-nous