Нестандартный интерпретатор арифметического выражения - VB
Формулировка задачи:
Я не нашёл на форуме интерпретатора арифметического выражения.
Поэтому последние три дня только им и занимался. И предлагаю вашему
вниманию действующую программу. Дана форма, на форме кнопка,
результат выносится в заголовок формы.
Особенности программы:
1. Выполняет четыре арифметических действия
2. Функции: s(x)=sin(x), c(x)=cos(x), m(x)=abs(x), e(x)=(x)
Зачем нужна функция e(x) , если она ничего не делает??
Ну 0 тоже в числе ничего не делает, а без него плохо.
Арифметическое выражение выглядит примерно так (1+2)*(3+4), а в программе
так е(e(1+2)*e(3+4)). Это моё Ноу-хау!! В программе используется рекурсивная
процедура. При каждом обращении к ней уменьшается пара скобок. И когда она
не находит скобку это означает, что все вычислено! Конечно у программы пока
слабая защита от любопытного пользователя. Если он введет в текстовое поле
например такой текст "Саша+Маша" , то тут нужен другой интерпретатор, этот
такого сложения не знает. Тем не менее он помогает тому, кто в этом нуждается
Например вводится арифметическое выражение. Если скобки вводятся неверно,
то кнопка становится сразу красной. Если все верно, то кнопка зелёная.
Если число скобок непарное то кнопка жёлтая.
Предполагается дальнейшее совершенствование этой программы.
Буду рад любым вашим советам, замечаниям и пожеланиям
по адресу этой программы. Поскольку она довольно сложная, то я
не жду быстрого ответа.
форма
модуль
Листинг программы
- Option Explicit
- Private Sub cmdCOM_Click()
- b = True
- Ti = txtT.Text
- Call Main(Ti)
- frmG.Caption = Str(All)
- End Sub
- Private Sub txtT_Change()
- Dim n As Integer
- Ti = txtT.Text
- n = Ccc(Ti)
- cmdCOM.BackColor = _
- Switch(n = 2, vbRed, n = 1, vbYellow, True, vbGreen)
- End Sub
Листинг программы
- Option Explicit
- Option Base 1
- Public i%, j%, ii%, dll%, c1%, c2%, cc%
- Public Xx!, Yy!
- Public Ti As String
- Public asd(100) As String
- Public b As Boolean, All!
- Public Sub Main(Tu As String)
- If Tu = "" Then Exit Sub
- If b Then
- Call Cubo(Tu, asd())
- For i = 2 To 100
- If asd(i) = " " Then
- dll = i: Exit For
- End If
- Next i
- b = False
- Xx = 1
- Yy = 2
- End If
- c2 = 0
- For i = 1 To dll
- If asd(i) = ")" Then
- c2 = i: GoTo 100
- End If
- Next i
- If c2 = 0 Then ' Скобок НЕТ - Вычисления окончены!!
- All = ini(asd(2))
- Exit Sub
- End If
- 100:
- For i = c2 - 2 To 1 Step -1
- If asd(i) = "(" Then
- c1 = i: Exit For
- End If
- Next i
- Call Mai2(asd())
- Call Main(Tu)
- End Sub
- Private Sub Mai2(fog() As String)
- Dim n As Integer, s As String
- fog(c1) = " " ' Долой скобки!!
- fog(c2) = " "
- ' Унарный минус (~)
- For i = c1 + 1 To c2 - 1
- If fog(i) = "~" Then
- fog(i) = Str(-ini(fog(i + 1)))
- Call Sdv1(i, c2)
- i = i - 1
- End If
- Next i
- ' Умножение и деление
- For i = c1 + 1 To c2 - 1
- If fog(i) = "*" Then
- fog(i - 1) = Str(ini(fog(i - 1)) * ini(fog(i + 1)))
- Call Sdv2(i, c2)
- i = i - 2
- ElseIf fog(i) = "/" Then
- If ini(fog(i + 1)) = 0 Then
- fog(i - 1) = "1"
- Else
- fog(i - 1) = Str(ini(fog(i - 1)) / ini(fog(i + 1)))
- End If
- Call Sdv2(i, c2)
- i = i - 2
- End If
- Next i
- ' Сложение и вычитание
- For i = c1 + 1 To c2 - 1
- If fog(i) = "+" Then
- fog(i - 1) = Str(ini(fog(i - 1)) + ini(fog(i + 1)))
- Call Sdv2(i, c2)
- i = i - 2
- ElseIf fog(i) = "-" Then
- fog(i - 1) = Str(ini(fog(i - 1)) - ini(fog(i + 1)))
- Call Sdv2(i, c2)
- i = i - 2
- End If
- Next i
- Select Case fog(c1 - 1)
- Case "s": fog(c1 - 1) = SStr(Sin(ini(fog(c1 + 1))))
- Case "c": fog(c1 - 1) = SStr(Cos(ini(fog(c1 + 1))))
- Case "m": fog(c1 - 1) = SStr(Abs(ini(fog(c1 + 1))))
- Case "e": fog(c1 - 1) = fog(c1 + 1)
- End Select
- cc = c2 - c1 + 1
- For i = c1 To dll - cc
- fog(i) = fog(i + cc)
- Next i
- dll = dll - cc
- End Sub
- ' Преобразует строку в массив
- Private Sub Cubo(ByVal Tu2 As String, mn() As String)
- Dim k As Integer, dol As Integer
- Dim R As String, R1 As String
- Tu2 = " " + Tu2 + " "
- dol = Len(Tu2)
- For i = 1 To dol
- R = Mid(Tu2, i, 1)
- R1 = Mid(Tu2, i + 1, 1)
- If Not Func(R) And (R1 = "(") Then
- Tu2 = Left(Tu2, i) + "e" + Right(Tu2, dol - i)
- End If
- R = Mid(Tu2, i, 1)
- R1 = Mid(Tu2, i + 1, 1)
- If ((R = "(") Or (R = " ")) And R1 = "-" Then
- Mid(Tu2, i + 1, 1) = "~"
- End If
- dol = Len(Tu2)
- Next i
- Tu2 = Trim(Tu2)
- Tu2 = " e(" + Tu2 + ") "
- ' ==============================
- Erase mn
- dol = Len(Tu2): k = 1 'k - Индекс массива
- i = 0
- Do
- i = i + 1
- R = Mid(Tu2, i, 1)
- If Not Ciff(R) Then
- mn(k) = R: k = k + 1: GoTo 100
- End If
- If Ciff(R) Then
- mn(k) = R
- R1 = Mid(Tu2, i + 1, 1)
- j = 1
- Do While Ciff(R1)
- mn(k) = mn(k) + R1
- j = j + 1
- R1 = Mid(Tu2, i + j, 1)
- Loop
- i = i + j - 1
- k = k + 1: GoTo 100
- End If
- 100:
- Loop Until i >= dol
- End Sub
- Private Function SStr(s As Single) As String
- SStr = LTrim(Str(s))
- End Function
- Private Sub Sdv1(c0%, c2%)
- For j = c0 To c2 - 2
- asd(j + 1) = asd(j + 2)
- Next j
- asd(c2) = " "
- End Sub
- Private Sub Sdv2(c0%, c2%)
- For j = c0 To c2 - 2
- asd(j) = asd(j + 2)
- Next j
- asd(c2) = " "
- asd(c2 - 1) = " "
- End Sub
- Private Function ini(Tex As String) As Single
- Select Case Tex
- Case "x": ini = Xx
- Case "y": ini = Yy
- Case Else
- ini = Val(Tex)
- End Select
- End Function
- Public Function Ccc(Tex As String) As Integer
- Dim R As String, ll%
- Ccc = 0
- ii = 0
- ll = Len(Tex)
- For i = 1 To ll
- R = Mid(Tex, i, 1)
- If R = "(" Then
- ii = ii + 1
- ElseIf R = ")" Then
- ii = ii - 1
- End If
- Next i
- Ccc = Switch(ii < 0, 2, ii > 0, 1, True, 0)
- End Function
- Public Function Func(FF As String) As Boolean
- Func = True
- If (FF <> "s") And (FF <> "c") And (FF <> "e") And (FF <> "m") Then Func = False
- End Function
- Public Function Ciff(uu As String) As Boolean
- Ciff = True
- If (uu <> "0") And (uu <> "1") And (uu <> "2") And (uu <> "3") And (uu <> "7") _
- And (uu <> "4") And (uu <> "5") And (uu <> "6") _
- And (uu <> "8") And (uu <> "9") And (uu <> ".") Then Ciff = False
- End Function
Решение задачи: «Нестандартный интерпретатор арифметического выражения»
textual
Листинг программы
- Sub Test()
- Dim ev As Eval
- Set ev = New Eval
- ev.SetVar "A", "3"
- ev.SetVar "B", "4"
- ev.Scalc "(A^2+B^2)^0.5", Res$
- Debug.Print Res$
- ev.Scalc "max(1,2,4,-5)", Res$
- Debug.Print Res$
- Set ev = Nothing
- End Sub
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д