簡體   English   中英

優先考慮python3中的算術運算符

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM