[英]giving precedence to arithmetic operators in python3
我正在服務器上實現一個簡單的算術計算,其中包括 add、sub、mul 和 Div,為了簡單起見,沒有執行其他操作,也沒有括號“()”來更改優先級。 我將為客戶提供的輸入類似於“1-2.1+3.6*5+10/2”(沒有點積,2.1 或 3.6 是一個浮點數)。 我創建了一個 function 來發送操作數和運算符,但一次我可以發送 udp 1 次計算的消息,格式為 (num1,op,num2)
import struct
import socket
ip = "127.0.0.1"
port = 11200
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) #creating socket
print("Do Ctrl+c to exit the program !!")
def sendRecv( num1, op, num2):
#sending udp message with num1,op and num
#receiving udp message with the result as res
res = s.recieve()
return res
sendRecv(in1, in_op, in2)
我能夠使用常規拆分拆分運算符和操作數並將它們分開
str = ['1', '-', '2.1', '+', '3.6', '*', '5', '+', '10', '/', '2']
因為乘法和除法優先於加法和減法 (3.6, *, 5) 應該先發送然后是除法,我正在嘗試用 while(len(str>0)) 編寫一個 while 循環,我正在嘗試要了解我如何首先發送乘法,將中間結果存儲在列表本身中並重復執行 function 直到所有計算都通過消息發送。 我不允許在客戶端執行任何操作,我只能將值發送到“SendRecv()”。 關於如何進行的任何建議或想法都會有所幫助。
提前致謝
根據運算符優先級遞歸拆分表達式:
def do_calc(num1, op, num2):
# Stub to represent the server call that performs one operation.
# Note that actually using eval() in your backend is REALLY BAD.
expr = f"{num1} {op} {num2}"
res = str(eval(expr))
print(expr, "=", res)
return res
def calc_loop(tokens):
if len(tokens) == 1:
return tokens[0]
if len(tokens) == 3:
return do_calc(*tokens)
for ops in "-+", "/*":
if any(op in tokens for op in ops):
op_idx = max(tokens.index(op) for op in ops if op in tokens)
return calc_loop([
calc_loop(tokens[:op_idx]),
tokens[op_idx],
calc_loop(tokens[op_idx+1:]),
])
expr = ['1', '-', '2.1', '+', '3.6', '*', '5', '+', '10', '/', '2']
print(' '.join(expr), '=', calc_loop(expr))
印刷:
1 - 2.1 = -1.1
3.6 * 5 = 18.0
10 / 2 = 5.0
18.0 + 5.0 = 23.0
-1.1 + 23.0 = 21.9
1 - 2.1 + 3.6 * 5 + 10 / 2 = 21.9
安排在給定的遍中僅處理特定的操作數。 進行多次傳遞,每次傳遞都有不同的操作符集。 拼接出現的答案。
def doWork(lst, ops):
lst = list(lst)
idx = 0
while idx < len(lst):
if lst[i] in ops:
lst[idx-1:idx+2] = sendRecv(*lst[idx-1:idx+2])
else:
idx += 1
return lst
results = doWork(str, '*/')
results = doWork(results, '+-')
results = results[0]
經典調車場算法的典型用例:
# operators and their precedences
ops = { '*': 2, '/': 2, '+': 1, '-': 1,}
# evaluate a stream of tokens
def evaluate(tokens):
vstack = []
ostack = []
def step():
v2 = vstack.pop()
v1 = vstack.pop()
op = ostack.pop()
vstack.append(sendRecv(v1, op, v2))
for tok in tokens:
if tok in ops:
if ostack and ops[ostack[-1]] >= ops[tok]:
step()
ostack.append(tok)
else:
vstack.append(tok)
while ostack:
step()
return vstack.pop()
# simulate the conversation with the server
def sendRecv(v1, op, v2):
res = eval(f'{v1} {op} {v2}')
return res
s = '3 + 4 * 2 + 3 / 5 + 6'
print(eval(s))
print(evaluate(s.split()))
謝謝大家提出不同的想法,我已經完成了自己的實現,並盡量保持簡單。 我不確定這對性能的影響是否不好,請告訴我:-)
def calc_buf(arr, operator):
i = 0
while (len(arr) > i):
if (arr[i] == operator):
calc = sendRecv(arr[i - 1], arr[i], arr[i + 1])
global arth_result
arth_result=calc
arr[i - 1] = calc
del arr[i]
del arr[i]
break
i += 1
return arr
arr =['1', '-', '2.1', '+', '3.6', '*', '5', '+', '10', '/', '2']
i = 0
while (count > i):
i = i + 1
if '/' in arr:
calc_buf(arr, '/')
elif "*" in arr:
calc_buf(arr, '*')
elif "-" in arr:
calc_buf(arr, '-')
elif "+" in arr:
calc_buf(arr, '+')
#print("actual evaluation:",eval(arth)) #for comparing the computation from server
print("result=", arth_result)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.