هي طريقة للتعبير عن العمليات الرياضية ولكن تختلف بأن ال operator يأتي دائما بعد المعاملات
فبدلا من ان تكتب 3 + 5 ستكتب 3 5 +
http://en.wikipedia.org/wiki/Reverse_Polish_notation
كل ماتحتاجه هو stack وتناسى الأقواس :)
يوجد مثال على ويكيبديا
اقتباسThe infix expression "5 + ((1 + 2) * 4) − 3" can be written down like this in RPN:
- 5 1 2 + 4 * + 3 -
كل الفكرة هي ان تنشئ stack تضع فيها ال tokens لتعبير ال rpn
إذا كان ال token رقم فقم بإضافته لل stack
إذا كان ال token عبارة عن operator -تحديدا binary operator- فقم بإزالة عنصرين من ال stack وقم بتطبيق ال operator عليهما
إذا كان ال token عبارة عن function تأخذ معامل واحد فقط قم بإزالة عنصر واحد من ال stack وقم بتطبيق الدالة عليه
import math
binop_to_func = {
"+" : lambda x,y : x+y,
"-" : lambda x,y : x-y,
"*" : lambda x,y : x*y,
"/" : lambda x,y : x*1./y,
"^" : lambda x,y : x**y,
"%" : lambda x,y : x%y,
}
mathfuncs = {'!':math.factorial }
for el in dir(math): #callable objects ( functions ) from math module
attr=getattr(math, el)
if callable(attr):
mathfuncs[el]=attr
def evaluateRPN(expr):
stack=[]
for tok in expr.split(" "):
if tok in binop_to_func.keys():
#pop the 2 arguments
n2=stack.pop()
n1=stack.pop()
stack.append(binop_to_func[tok](n1,n2))
elif tok in mathfuncs:
#pop only 1 argument
arg = stack.pop()
stack.append(mathfuncs[tok](arg))
else:
stack.append(int(tok))
if len(stack) == 1:
return stack[0]
if __name__=="__main__":
while True:
try:
expr=raw_input("[RPN]> ")
print(evaluateRPN(expr))
except:
pass
ملاحظة
mathfuncs = {'!':math.factorial }
for el in dir(math): #callable objects ( functions ) from math module
attr=getattr(math, el)
if callable(attr):
mathfuncs[el]=attrفي هذه الجزئية استخدمنا قليل من سحر بايثون فبدلا من كتابة كل عناصر math في القاموس قمنا بإستخدام dir للحصول على جميع عناصر وحدة math
ومنها نحصل على كل attribute قابلة للإستدعاء -دالة-
ونقوم بإضافة الإسم كمفتاح والدالة كقيمة