03-10-12, 12:34 PM
كاتب الموضوع : محمد شريقي
بسم الله الرحمن الرحيم
كنت قد كتبت هذه الدروس الاربعة السابقة
هياكل البيانات Data Structures الصف Queue : الجزء الاول
هياكل البيانات Data Structures المكدس Stack: الجزء الثاني
التعريف بـ PostFix و PreFix و InFix ومجالات استخدامهم : الدرس الثالث
التحويل من Infix الى postfix و prefix : الدرس الرابع
واعتقد ان الاغلب لم يهتم بهم لانه لا يعلم بما سيستخدمهم
لذا جاء هذا الشرح لبيان اهمية الدروس السابقة
لنفترض ان لدينا تكست بوكس ونريد ان يدخل المستخدم صيغة رياضية وتريد ان يحسب البرنامج قيمة الصيغة مثلا اذا كتب المستخدم
يجب ان يرد البرنامج
11
او اذا كتب
يجب ان يرد البرنامج 25
او اذا كتب
يجب ان يرد البرنامج 75
او حتى باستخدام الرفع للقوة او الجذر من المرتبة N او لوغاريتم او اي شيء اخر
يجب ان يقوم البرنامج بحساب الناتج
لنرى كيف يتم ذلك
[SIZE=5]الخطوة الاولى :
يجب كتابة الصيغة باحدى الطريقتين postfix او prefix
وهذا شيء تعلمناه في الدرس الرابع
وهاهو التابع المسؤول عن ذلك ولكني قمت ببعض التعديلات عليه من اجل ان يعيد القيمة داخل صف queue (راجع الدرس الاول)
وليس داخل متغير نصي String
وايضا قمت بتعديل آخر هام جداً وهو من اجل الارقام التي تتكون من اكثر من خانة مثلا 11 او 1648
حيث يتكون من احاد وعشرات و .... الخ
وهاهو كود التابع بطريقة postfix
InfixToPostfix
لاحظ الكود جديد هذا
ومهمته التأكد من الرمز اللاحق فإذا كان معامل يكون الرقم يتكون من اكثر من خانة ويقوم بالمطلوب
وهنا الطريقة الثانية prefix
InfixToPrefix
هنا نكون انتهينا من كود التحويل من infix الى postfix او prefix
الخطوة الثانية :
حتى نستطيع معرفة الناتج نتبع التالي
في صيغة postfix
نقوم بفحص القيم واحد تلو الاخر بواسطة التابع isopr الموجود في الدرس الرابع
وهاهو للتذكير فقط
اذا كان الخرج هو عدد (معامل operand)
ندخل العدد الى مكدس (راجع الدرس الثاني)
اما اذا كان الخرج هو عامل Operator
نسحب اخر قيمتين من المكدس بواسطة pop طبعا (راجع الدرس الثاني)
ثم نممررهم مع العامل الى الدالة calculat لتقوم بحساب الناتج وتعيده ونقوم بوضع الناتج بالمكدس push
وهنا جسم الدالة calculat
وهي واضحة ليست بحاجة للشرح على ما اعتقد
وبعد المرور على جميع المدخلات
سيظهر لنا الناتج بقمة المكدس
نقوم باستخراجه pop وعرضه للمستخدم
وهذا كود التابع السابق ذكره
اما بالنسبة للصيغة المكتوبة بالـ prefix
فهي نفس الخطوات ولكن بتبديل الترتيب الـ operands
اعتذر عن الاختصار بالشرح ولكن هذا بسبب التعب سامحوني
وفي النهاية هذا كود البرنامج كاملا بعد اضافة داله للتأكد من الازرار المدخلة الى التكست وعدم السماح بادخال ما هو غير ملائم
فقط قم باضافة 2 كومند وتكست بوكس
وهذا البرنامج بالمرفقات
او من هذا الرابط
Real Calculator
واي سؤال انا جاهز بإذن الله
وسامحوني على الاطالة والسلام عليكم[/SIZE]
بسم الله الرحمن الرحيم
كنت قد كتبت هذه الدروس الاربعة السابقة
هياكل البيانات Data Structures الصف Queue : الجزء الاول
هياكل البيانات Data Structures المكدس Stack: الجزء الثاني
التعريف بـ PostFix و PreFix و InFix ومجالات استخدامهم : الدرس الثالث
التحويل من Infix الى postfix و prefix : الدرس الرابع
واعتقد ان الاغلب لم يهتم بهم لانه لا يعلم بما سيستخدمهم
لذا جاء هذا الشرح لبيان اهمية الدروس السابقة
لنفترض ان لدينا تكست بوكس ونريد ان يدخل المستخدم صيغة رياضية وتريد ان يحسب البرنامج قيمة الصيغة مثلا اذا كتب المستخدم
كود :
5+6
11
او اذا كتب
كود :
5*(2+3)
او اذا كتب
كود :
5^(1+3)/25*(2+1)
او حتى باستخدام الرفع للقوة او الجذر من المرتبة N او لوغاريتم او اي شيء اخر
يجب ان يقوم البرنامج بحساب الناتج
لنرى كيف يتم ذلك
[SIZE=5]الخطوة الاولى :
يجب كتابة الصيغة باحدى الطريقتين 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
الخطوة الثانية :
حتى نستطيع معرفة الناتج نتبع التالي
في صيغة postfix
نقوم بفحص القيم واحد تلو الاخر بواسطة التابع isopr الموجود في الدرس الرابع
وهاهو للتذكير فقط
كود :
Private Function IsOpr(ByVal OPR As String) As Boolean
Select Case OPR
Case "+", "-", "*", "/", ")", "(", "^", "%"
Return True
Case Else
Return False
End Select
ندخل العدد الى مكدس (راجع الدرس الثاني)
اما اذا كان الخرج هو عامل 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
فهي نفس الخطوات ولكن بتبديل الترتيب الـ 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
او من هذا الرابط
Real Calculator
واي سؤال انا جاهز بإذن الله
وسامحوني على الاطالة والسلام عليكم[/SIZE]