中缀表达式求值(支持浮点数与负数)程序开发需求
Got it, let's build exactly what you need: a program that uses the 2-stack method to evaluate infix expressions, with a loop to keep asking users for new inputs, plus proper handling of that underscore-based negative notation. Here's a complete breakdown and implementation:
Key Requirements Covered
- Loop to prompt users for new expressions until they don't enter "yes"
- Echo the input expression exactly as entered
- 2-stack method for infix evaluation
- Support for floating-point numbers and underscore-prefixed negatives (e.g.,
_3.14159=-3.14159)
Python Implementation
def evaluate_expression(expr): # Define operator precedence (higher number = higher priority) precedence = {'+': 1, '-': 1, '*': 2, '/': 2} op_stack = [] num_stack = [] i = 0 n = len(expr) while i < n: char = expr[i] # Skip whitespace characters if char == ' ': i += 1 continue # Handle numbers (including floats and underscore-prefixed negatives) if char.isdigit() or char == '.' or char == '_': num_str = '' # Convert underscore to negative sign if char == '_': num_str += '-' i += 1 if i >= n: raise ValueError("Invalid negative number: underscore has no trailing digits") # Collect all digits and decimal points for the number while i < n and (expr[i].isdigit() or expr[i] == '.'): num_str += expr[i] i += 1 # Parse to float and push to number stack num_stack.append(float(num_str)) # Handle left parentheses elif char == '(': op_stack.append(char) i += 1 # Handle right parentheses: evaluate until matching left parenthesis elif char == ')': while op_stack and op_stack[-1] != '(': op = op_stack.pop() b = num_stack.pop() a = num_stack.pop() if op == '+': num_stack.append(a + b) elif op == '-': num_stack.append(a - b) elif op == '*': num_stack.append(a * b) elif op == '/': num_stack.append(a / b) op_stack.pop() # Remove the matching left parenthesis i += 1 # Handle operators: apply precedence rules elif char in precedence: while op_stack and op_stack[-1] != '(' and precedence[op_stack[-1]] >= precedence[char]: op = op_stack.pop() b = num_stack.pop() a = num_stack.pop() if op == '+': num_stack.append(a + b) elif op == '-': num_stack.append(a - b) elif op == '*': num_stack.append(a * b) elif op == '/': num_stack.append(a / b) op_stack.append(char) i += 1 # Invalid character handling else: raise ValueError(f"Unrecognized character: '{char}'") # Evaluate remaining operators in the stack while op_stack: op = op_stack.pop() b = num_stack.pop() a = num_stack.pop() if op == '+': num_stack.append(a + b) elif op == '-': num_stack.append(a - b) elif op == '*': num_stack.append(a * b) elif op == '/': num_stack.append(a / b) return num_stack[-1] # Loop for user interaction while True: user_choice = input("Do you want to enter an infix expression? (yes/no): ").strip().lower() if user_choice != 'yes': print("Exiting the program...") break expr_input = input("Enter your infix expression: ").strip() print(f"You entered: {expr_input}") try: result = evaluate_expression(expr_input) print(f"Evaluation result: {result}\n") except Exception as e: print(f"Error evaluating expression: {str(e)}\n")
How It Works
1. Loop Interaction
The outer while True loop keeps asking if you want to enter a new expression. It only exits when you type anything other than "yes".
2. 2-Stack Evaluation Logic
- Number Stack: Stores all operands (integers and floats, including negatives converted from underscore notation)
- Operator Stack: Stores operators and parentheses, following precedence rules to ensure correct order of operations
- When encountering a right parenthesis, we evaluate all operations inside the parentheses until we hit the matching left parenthesis.
3. Negative Number Handling
When the parser sees an underscore _, it converts it to a negative sign - and collects the following digits/decimal points to form a valid negative number.
Test Your Sample Data
Test Case 1
Input expression: 3*(4+2*(6-4)+1)+2*3
- Echoed input:
3*(4+2*(6-4)+1)+2*3 - Result:
33.0
Test Case 2
(Note: Replace the Chinese en dash – with an English minus sign - for valid input)
Input expression: 2.75 * ((3 + 1.) - (_3.14159*7+3.1))
- Echoed input:
2.75 * ((3 + 1.) - (_3.14159*7+3.1)) - Result:
62.9506075
Important Notes
- Use English operators (
+,-,*,/) — non-English symbols will trigger errors - Underscores can only be used at the start of a negative number (e.g.,
_3.14is valid,3._14is not) - The program handles mixed integer and floating-point operations seamlessly
内容的提问来源于stack exchange,提问作者user3473451

