تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
حساب قيمة معادلة(اقصد صيغة دون مجاهيل) مكتوبة بالتكست : الجزء الخامس والاخير
#1
[COLOR="#000080"]بسم الله الرحمن الرحيم

كنت قد كتبت هذه الدروس الاربعة السابقة

هياكل البيانات Data Structures الصف Queue : الجزء الاول

هياكل البيانات Data Structures المكدس Stack: الجزء الثاني

التعريف بـ PostFix و PreFix و InFix ومجالات استخدامهم : الجزء الثالث

[url="http://vb4arb.com/vb/showthread.php?1078-%C7%E1%CA%CD%E6%ED%E1-%E3%E4-Infix-%C7%E1%EC-postfix-%E6-prefix-%C7%E1%CC%D2%C1-%C7%E1%D1%C7%C8%DA&p=3082#post3082"]التحويل من Infix الى postfix و prefix : الجزء الرابع
[/url]
واعتقد ان الاغلب لم يهتم بهم لانه لا يعلم بما سيستخدمهم
لذا جاء هذا الشرح لبيان اهمية الدروس السابقة

لنفترض ان لدينا تكست بوكس ونريد ان يدخل المستخدم صيغة رياضية وتريد ان يحسب البرنامج قيمة الصيغة مثلا اذا كتب المستخدم
كود :
5+6

يجب ان يرد البرنامج
11

او اذا كتب
كود :
5*(2+3)

يجب ان يرد البرنامج 25

او اذا كتب
كود :
5^(1+3)/25*(2+1)

يجب ان يرد البرنامج 75

او حتى باستخدام الرفع للقوة او الجذر من المرتبة N او لوغاريتم او اي شيء اخر
يجب ان يقوم البرنامج بحساب الناتج

لنرى كيف يتم ذلك

الخطوة الاولى :

يجب كتابة الصيغة باحدى الطريقتين postfix او prefix
وهذا شيء تعلمناه في الدرس الرابع

وهاهو التابع المسؤول عن ذلك ولكني قمت ببعض التعديلات عليه من اجل ان يعيد القيمة داخل صف queue (راجع الدرس الاول)
وليس داخل متغير نصي String

وايضا قمت بتعديل آخر هام جداً وهو من اجل الارقام التي تتكون من اكثر من خانة مثلا 11 او 1648
حيث يتكون من احاد وعشرات و .... الخ

وهاهو كود التابع بطريقة postfix
InfixToPostfix

كود :
Private Function InfixToPostfix(ByVal infix As String) As Queue(Of String)
        Dim RESULT As New Queue(Of String), S As New Stack(Of String), multnum As String = ""
        For i = 1 To infix.Length
            Dim Temp As String = Mid(infix, i, 1)
            If IsOpr(Temp) = False Then
                multnum &= Temp
                If i < infix.Length Then
                    Dim NextTemp As String = ""
                    NextTemp = Mid(infix, i + 1, 1)
                    If IsOpr(NextTemp) Then
                        RESULT.Enqueue(multnum)
                        multnum = ""
                    End If
                Else
                    RESULT.Enqueue(multnum)
                End If
            Else
                If Temp = ")" Then
                    Do Until S.Peek = "("
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Pop()
                ElseIf Temp = "(" Then
                    S.Push(Temp)
                Else
                    Do While S.Count > 0 AndAlso Prio(S.Peek) >= Prio(Temp) AndAlso S.Peek <> "("
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Push(Temp)
                End If
            End If
        Next

        Do While S.Count > 0
            RESULT.Enqueue(S.Pop)
        Loop

        Return RESULT
    End Function

لاحظ الكود جديد هذا
كود :
multnum &= Temp
                If i < infix.Length Then
                    Dim NextTemp As String = ""
                    NextTemp = Mid(infix, i + 1, 1)
                    If IsOpr(NextTemp) Then
                        RESULT.Enqueue(multnum)
                        multnum = ""
                    End If
                Else
                    RESULT.Enqueue(multnum)
                End If
ومهمته التأكد من الرمز اللاحق فإذا كان معامل يكون الرقم يتكون من اكثر من خانة ويقوم بالمطلوب


وهنا الطريقة الثانية prefix
InfixToPrefix
كود :
Private Function InfixToPrefix(ByVal infix As String) As Queue(Of String)
        Dim RESULT As New Queue(Of String), S As New Stack(Of String), multnum As String = ""
        Dim TT As String = infix
        infix = ""
        For i = TT.Length To 1 Step -1
            infix &= Mid(TT, i, 1)
        Next
        ' reverse the infix expr

        For i = 1 To infix.Length
            Dim Temp As String = Mid(infix, i, 1)
            If IsOpr(Temp) = False Then
                multnum = Temp & multnum
                If i < infix.Length Then
                    Dim NextTemp As String = ""
                    NextTemp = Mid(infix, i + 1, 1)
                    If IsOpr(NextTemp) Then
                        RESULT.Enqueue(multnum)
                        multnum = ""
                    End If
                Else
                    RESULT.Enqueue(multnum)
                End If
            Else
                If Temp = "(" Then
                    Do Until S.Peek = ")"
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Pop()
                ElseIf Temp = ")" Then
                    S.Push(Temp)
                Else
                    Do While S.Count > 0 AndAlso Prio(S.Peek) > Prio(Temp) AndAlso S.Peek <> ")"
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Push(Temp)
                End If
            End If
        Next

        Do While S.Count > 0
            RESULT.Enqueue(S.Pop)
        Loop

        Return RESULT
    End Function
هنا نكون انتهينا من كود التحويل من infix الى postfix او prefix

الخطوة الثانية :
حتى نستطيع معرفة الناتج نتبع التالي
في صيغة postfix
نقوم بفحص القيم واحد تلو الاخر بواسطة التابع isopr الموجود في الدرس الرابع
وهاهو للتذكير فقط
كود :
Private Function IsOpr(ByVal OPR As String) As Boolean
        Select Case OPR
            Case "+", "-", "*", "/", ")", "(", "^", "%"
                Return True
            Case Else
                Return False
        End Select
اذا كان الخرج هو عدد (معامل operand)
ندخل العدد الى مكدس (راجع الدرس الثاني)
اما اذا كان الخرج هو عامل Operator
نسحب اخر قيمتين من المكدس بواسطة pop طبعا (راجع الدرس الثاني)
ثم نممررهم مع العامل الى الدالة calculat لتقوم بحساب الناتج وتعيده ونقوم بوضع الناتج بالمكدس push

وهنا جسم الدالة calculat
كود :
Private Function CalCulat(ByVal A As Long, ByVal opr As String, ByVal B As Long) As Double
        Select Case opr
            Case "^"
                Return A ^ B
            Case "%"
                Return A ^ (1 / B)
            Case "*"
                Return A * B
            Case "/"
                Return A / B
            Case "+"
                Return A + B
            Case "-"
                Return A - B
            Case Else
                Return 0
        End Select
    End Function
وهي واضحة ليست بحاجة للشرح على ما اعتقد
وبعد المرور على جميع المدخلات
سيظهر لنا الناتج بقمة المكدس
نقوم باستخراجه pop وعرضه للمستخدم

وهذا كود التابع السابق ذكره
كود :
Private Function postfixresult(ByRef post As Queue(Of String)) As Double
        On Error Resume Next
        Dim S As New Stack(Of String)
        Do While post.Count > 0
            Dim Temp As String = post.Dequeue
            If IsOpr(Temp) = False Then
                S.Push(Temp)
            Else
                Dim B As Long = S.Pop
                Dim A As Long = S.Pop
                S.Push(CalCulat(A, Temp, B))
            End If
        Loop
        Return S.Pop
اما بالنسبة للصيغة المكتوبة بالـ prefix
فهي نفس الخطوات ولكن بتبديل الترتيب الـ operands
كود :
Private Function prefixresult(ByRef post As Queue(Of String)) As Double
        On Error Resume Next
        Dim S As New Stack(Of String)
        Do While post.Count > 0
            Dim Temp As String = post.Dequeue
            If IsOpr(Temp) = False Then
                S.Push(Temp)
            Else
                Dim A As Long = S.Pop
                Dim B As Long = S.Pop
                S.Push(CalCulat(A, Temp, B))
            End If
        Loop
        Return S.Pop
    End Function
اعتذر عن الاختصار بالشرح ولكن هذا بسبب التعب سامحوني
وفي النهاية هذا كود البرنامج كاملا بعد اضافة داله للتأكد من الازرار المدخلة الى التكست وعدم السماح بادخال ما هو غير ملائم
فقط قم باضافة 2 كومند وتكست بوكس
كود :
Public Class Form1

    Private Function InfixToPostfix(ByVal infix As String) As Queue(Of String)
        Dim RESULT As New Queue(Of String), S As New Stack(Of String), multnum As String = ""
        For i = 1 To infix.Length
            Dim Temp As String = Mid(infix, i, 1)
            If IsOpr(Temp) = False Then
                multnum &= Temp
                If i < infix.Length Then
                    Dim NextTemp As String = ""
                    NextTemp = Mid(infix, i + 1, 1)
                    If IsOpr(NextTemp) Then
                        RESULT.Enqueue(multnum)
                        multnum = ""
                    End If
                Else
                    RESULT.Enqueue(multnum)
                End If
            Else
                If Temp = ")" Then
                    Do Until S.Peek = "("
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Pop()
                ElseIf Temp = "(" Then
                    S.Push(Temp)
                Else
                    Do While S.Count > 0 AndAlso Prio(S.Peek) >= Prio(Temp) AndAlso S.Peek <> "("
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Push(Temp)
                End If
            End If
        Next

        Do While S.Count > 0
            RESULT.Enqueue(S.Pop)
        Loop

        Return RESULT
    End Function

    Private Function InfixToPrefix(ByVal infix As String) As Queue(Of String)
        Dim RESULT As New Queue(Of String), S As New Stack(Of String), multnum As String = ""
        Dim TT As String = infix
        infix = ""
        For i = TT.Length To 1 Step -1
            infix &= Mid(TT, i, 1)
        Next
        ' reverse the infix expr

        For i = 1 To infix.Length
            Dim Temp As String = Mid(infix, i, 1)
            If IsOpr(Temp) = False Then
                multnum = Temp & multnum
                If i < infix.Length Then
                    Dim NextTemp As String = ""
                    NextTemp = Mid(infix, i + 1, 1)
                    If IsOpr(NextTemp) Then
                        RESULT.Enqueue(multnum)
                        multnum = ""
                    End If
                Else
                    RESULT.Enqueue(multnum)
                End If
            Else
                If Temp = "(" Then
                    Do Until S.Peek = ")"
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Pop()
                ElseIf Temp = ")" Then
                    S.Push(Temp)
                Else
                    Do While S.Count > 0 AndAlso Prio(S.Peek) > Prio(Temp) AndAlso S.Peek <> ")"
                        RESULT.Enqueue(S.Pop)
                    Loop
                    S.Push(Temp)
                End If
            End If
        Next

        Do While S.Count > 0
            RESULT.Enqueue(S.Pop)
        Loop

        Return RESULT
    End Function

    Private Function IsOpr(ByVal OPR As String) As Boolean
        Select Case OPR
            Case "+", "-", "*", "/", ")", "(", "^", "%"
                Return True
            Case Else
                Return False
        End Select
    End Function

    Private Function Prio(ByVal Sym As String) As Integer
        Select Case Sym
            Case "^", "%"
                Return 4
            Case "*", "/"
                Return 2
            Case "+", "-"
                Return 1
            Case Else
                Return 0
        End Select
    End Function

    Private Function CalCulat(ByVal A As Long, ByVal opr As String, ByVal B As Long) As Double
        Select Case opr
            Case "^"
                Return A ^ B
            Case "%"
                Return A ^ (1 / B)
            Case "*"
                Return A * B
            Case "/"
                Return A / B
            Case "+"
                Return A + B
            Case "-"
                Return A - B
            Case Else
                Return 0
        End Select
    End Function

    Private Function postfixresult(ByRef post As Queue(Of String)) As Double
        On Error Resume Next
        Dim S As New Stack(Of String)
        Do While post.Count > 0
            Dim Temp As String = post.Dequeue
            If IsOpr(Temp) = False Then
                S.Push(Temp)
            Else
                Dim B As Long = S.Pop
                Dim A As Long = S.Pop
                S.Push(CalCulat(A, Temp, B))
            End If
        Loop
        Return S.Pop
    End Function

    Private Function prefixresult(ByRef post As Queue(Of String)) As Double
        On Error Resume Next
        Dim S As New Stack(Of String)
        Do While post.Count > 0
            Dim Temp As String = post.Dequeue
            If IsOpr(Temp) = False Then
                S.Push(Temp)
            Else
                Dim A As Long = S.Pop
                Dim B As Long = S.Pop
                S.Push(CalCulat(A, Temp, B))
            End If
        Loop
        Return S.Pop
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MessageBox.Show("The Result Is : " & postfixresult(InfixToPostfix(TextBox1.Text)), "PostFix Type")
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        MessageBox.Show("The Result Is : " & prefixresult(InfixToPrefix(TextBox1.Text)), "PreFix Type")
    End Sub

    Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        Select Case e.KeyChar
            Case "0" To "9", ControlChars.Back, "^", "%", "*", "/", "+", "-", "(", ")"
                e.Handled = False
            Case Else
                e.Handled = True
        End Select
    End Sub

End Class
وهذا البرنامج بالمرفقات

واي سؤال انا جاهز بإذن الله
وسامحوني على الاطالة والسلام عليكم[/COLOR]


الملفات المرفقة
.rar   Real Calculator.rar (الحجم : 77.92 ك ب / التحميلات : 40)
الرد }}}}
تم الشكر بواسطة:
#2
اضافة بعض المزايا قريبا
الرد }}}}
تم الشكر بواسطة:
#3
السلام عليكم ورحمة الله وبركاته

ما شاء الله عليك أخي الكريم
زادك الله علما وفضلا
وبارك فيك
وجعله في ميزان حسناتك

بالتوفيق
الرد }}}}
تم الشكر بواسطة:
#4
السلام عليكم

بارك الله فيك وجزاك خيرا
الرد }}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  درس: كيفية حساب عدد الأسطر في نص المبرمج الطموح vb6 4 1,621 04-08-15, 12:45 AM
آخر رد: العواد الصغير
  تحويل الفيديو في برامجك-الجزء الثاني( إصلاح للمشاكل + تعديل للروابط + توضيح للأمر ) RaggiTech 1 712 10-12-14, 06:37 PM
آخر رد: abulayth
  الجزء الثالث من:كيف تجعل الـ Text Box ذكي!يترجم العمليات الحسابية ويخرج الناتج (الأقواس المتعددة) !! أنس محمود 9 2,073 06-12-14, 10:11 PM
آخر رد: RFEE3 ALSHAN
  الجزء الثاني من:كيف تجعل الـ Text Box ذكي!يترجم العمليات الحسابية ويخرج الناتج ( العمليات المتعددة)! أنس محمود 0 689 22-02-13, 12:39 AM
آخر رد: أنس محمود
  مقال- تطوير الكونترول Property Attributes الجزء الثالث RaggiTech 0 365 06-10-12, 12:20 AM
آخر رد: RaggiTech
  الجزء الثاني - تطوير الكونترول Interfaces RaggiTech 0 385 06-10-12, 12:19 AM
آخر رد: RaggiTech
  كود- حساب مواقيت الصلاة Prayer Times في الدوت نت 2008 و 2005 RaggiTech 0 1,471 05-10-12, 01:48 PM
آخر رد: RaggiTech
  مقال- Custom EventHandler &amp; Classes - الجزء الثاني RaggiTech 0 356 05-10-12, 11:50 AM
آخر رد: RaggiTech
  مقال- Custom EventHandler &amp; Classes - الجزء الأول RaggiTech 6 648 05-10-12, 11:48 AM
آخر رد: RaggiTech
  مقال- أفكار في الجرافكس ..... الجزء الثالث RaggiTech 3 470 05-10-12, 11:42 AM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم