Tôi hiện đang chuyển từ Java sang Python và đã thực hiện nhiệm vụ cố gắng tạo một máy tính có thể thực hiện các hoạt động biểu tượng trên biểu thức toán học được mã hóa (mà không sử dụng các mô-đun tùy chỉnh như Sympy). Hiện tại, nó được xây dựng để chấp nhận các chuỗi được phân tách bằng dấu cách và chỉ có thể thực hiện toán tử (,), +, -, * và /. Thật không may, tôi không thể tìm ra thuật toán cơ bản để đơn giản hóa các biểu thức biểu tượng.Tôi có thể viết một hàm thực hiện các phép tính biểu tượng trong Python 2.7 không?
Ví dụ, với chuỗi '2 * ((9/6) + 6 * x)', chương trình của tôi nên thực hiện các bước sau:
- 2 * (1,5 + 6 * x)
- 3 + 12 * x
Nhưng tôi không thể có được những chương trình để bỏ qua x khi phân phối 2.
Bên cạnh đó, làm thế nào tôi có thể xử lý 'x * 6/x' để nó trở về ' 6 'sau khi đơn giản hóa?
EDIT: Để làm rõ, bằng "tượng trưng" tôi có nghĩa là nó sẽ để lại các chữ cái như "A" và "f" ở đầu ra trong khi thực hiện các phép tính còn lại.
CHỈNH SỬA 2: Tôi (chủ yếu) đã hoàn tất mã. Tôi đăng nó ở đây nếu có ai vấp phải bài viết này trong tương lai, hoặc nếu có ai trong số các bạn tò mò.
def reduceExpr(useArray):
# Use Python's native eval() to compute if no letters are detected.
if (not hasLetters(useArray)):
return [calculate(useArray)] # Different from eval() because it returns string version of result
# Base case. Returns useArray if the list size is 1 (i.e., it contains one string).
if (len(useArray) == 1):
return useArray
# Base case. Returns the space-joined elements of useArray as a list with one string.
if (len(useArray) == 3):
return [' '.join(useArray)]
# Checks to see if parentheses are present in the expression & sets.
# Counts number of parentheses & keeps track of first (found.
parentheses = 0
leftIdx = -1
# This try/except block is essentially an if/else block. Since useArray.index('(') triggers a KeyError
# if it can't find '(' in useArray, the next line is not carried out, and parentheses is not incremented.
try:
leftIdx = useArray.index('(')
parentheses += 1
except Exception:
pass
# If a KeyError was returned, leftIdx = -1 and rightIdx = parentheses = 0.
rightIdx = leftIdx + 1
while (parentheses > 0):
if (useArray[rightIdx] == '('):
parentheses += 1
elif (useArray[rightIdx] == ')'):
parentheses -= 1
rightIdx += 1
# Provided parentheses pair isn't empty, runs contents through again; else, removes the parentheses
if (leftIdx > -1 and rightIdx - leftIdx > 2):
return reduceExpr(useArray[:leftIdx] + [' '.join(['(',reduceExpr(useArray[leftIdx+1:rightIdx-1])[0],')'])] + useArray[rightIdx:])
elif (leftIdx > -1):
return reduceExpr(useArray[:leftIdx] + useArray[rightIdx:])
# If operator is + or -, hold the first two elements and process the rest of the list first
if isAddSub(useArray[1]):
return reduceExpr(useArray[:2] + reduceExpr(useArray[2:]))
# Else, if operator is * or /, process the first 3 elements first, then the rest of the list
elif isMultDiv(useArray[1]):
return reduceExpr(reduceExpr(useArray[:3]) + useArray[3:])
# Just placed this so the compiler wouldn't complain that the function had no return (since this was called by yet another function).
return None
Tôi nghĩ bạn đang bắt đầu thấy được đức tính của Sympy :-) Tôi nghĩ bạn đang xem xét việc xây dựng một trình phân tích cú pháp gốc đệ quy cho biểu thức số học, tiếp theo là thao tác của cây dữ liệu để giải quyết X. – wberry
CÓ !!! Bạn có thể;) – Drakosha
@ li.davidm Nó vẫn đang trong giai đoạn logic ngay bây giờ. Tôi không thể tìm ra cách để thực hiện qua khối cản trở đầu tiên. – Edwin