|
发表于 2023-10-15 18:05:28
|
显示全部楼层
问题描述:
我需要使用C语言实现中缀表达式的求值算法。请提供完整的回答,包括代码和解释。
解决方案:
要实现中缀表达式的求值,通常使用栈这种数据结构来辅助计算。以下是一个基本的中缀表达式求值算法的实现示例:
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <ctype.h>
- // 定义栈结构
- typedef struct {
- int capacity;
- int top;
- int* array;
- } Stack;
- // 创建一个新的栈
- Stack* createStack(int capacity) {
- Stack* stack = (Stack*)malloc(sizeof(Stack));
- stack->capacity = capacity;
- stack->top = -1;
- stack->array = (int*)malloc(stack->capacity * sizeof(int));
- return stack;
- }
- // 判断栈是否为空
- bool isEmpty(Stack* stack) {
- return stack->top == -1;
- }
- // 判断栈是否已满
- bool isFull(Stack* stack) {
- return stack->top == stack->capacity - 1;
- }
- // 入栈
- void push(Stack* stack, int item) {
- if (isFull(stack)) {
- printf("栈已满\n");
- return;
- }
- stack->array[++stack->top] = item;
- }
- // 出栈
- int pop(Stack* stack) {
- if (isEmpty(stack)) {
- printf("栈为空\n");
- return '\0';
- }
- return stack->array[stack->top--];
- }
- // 获取栈顶元素
- int peek(Stack* stack) {
- if (isEmpty(stack)) {
- printf("栈为空\n");
- return '\0';
- }
- return stack->array[stack->top];
- }
- // 操作符的优先级
- int precedence(char op) {
- switch (op) {
- case '+':
- case '-':
- return 1;
- case '*':
- case '/':
- return 2;
- case '^':
- return 3;
- }
- return -1;
- }
- // 执行算术运算
- int performOperation(int operand1, int operand2, char operator) {
- switch (operator) {
- case '+':
- return operand1 + operand2;
- case '-':
- return operand1 - operand2;
- case '*':
- return operand1 * operand2;
- case '/':
- return operand1 / operand2;
- case '^':
- return pow(operand1, operand2); // 需要包含 math.h 头文件
- }
- return 0;
- }
- // 中缀表达式求值
- int evaluateInfixExpression(char* expression) {
- Stack* operandStack = createStack(strlen(expression));
- Stack* operatorStack = createStack(strlen(expression));
- for (int i = 0; i < strlen(expression); i++) {
- if (expression[i] == ' ' || expression[i] == '\t') {
- continue;
- }
- else if (isdigit(expression[i])) {
- int operand = 0;
- while (i < strlen(expression) && isdigit(expression[i])) {
- operand = (operand * 10) + (expression[i] - '0');
- i++;
- }
- i--;
- push(operandStack, operand);
- }
- else if (expression[i] == '(') {
- push(operatorStack, expression[i]);
- }
- else if (expression[i] == ')') {
- while (!isEmpty(operatorStack) && peek(operatorStack) != '(') {
- int operand2 = pop(operandStack);
- int operand1 = pop(operandStack);
- char op = pop(operatorStack);
- int result = performOperation(operand1, operand2, op);
- push(operandStack, result);
- }
- if (!isEmpty(operatorStack) && peek(operatorStack) != '(') {
- printf("非法表达式\n");
- return -1;
- }
- else {
- pop(operatorStack);
- }
- }
- else if (expression[i] == '+' || expression[i] == '-' ||
- expression[i] == '*' || expression[i] == '/' || expression[i] == '^') {
- while (!isEmpty(operatorStack) && precedence(expression[i]) <= precedence(peek(operatorStack))) {
- int operand2 = pop(operandStack);
- int operand1 = pop(operandStack);
- char op = pop(operatorStack);
- int result = performOperation(operand1, operand2, op);
- push(operandStack, result);
- }
- push(operatorStack, expression[i]);
- }
- }
- while (!isEmpty(operatorStack)) {
- int operand2 = pop(operandStack);
- int operand1 = pop(operandStack);
- char op = pop(operatorStack);
- int result = performOperation(operand1, operand2, op);
- push(operandStack, result);
- }
- int finalResult = pop(operandStack);
- free(operandStack);
- free(operatorStack);
- return finalResult;
- }
- int main() {
- char expression[100];
- printf("请输入中缀表达式:");
- gets(expression);
- int result = evaluateInfixExpression(expression);
- printf("结果为:%d\n", result);
- return 0;
- }
复制代码
上述示例代码中,我们使用两个栈 operandStack 和 operatorStack 来辅助求值。operandStack 用于存储操作数,而 operatorStack 用于存储运算符。
算法的基本思路是遍历中缀表达式中的每个字符,根据不同的情况进行处理。当遇到数字时,将其解析为操作数并入栈 operandStack;当遇到左括号时,将其入栈 operatorStack;当遇到右括号时,执行栈操作直到遇到左括号,并将结果入栈 operandStack;当遇到运算符时,与 operatorStack 栈顶元素比较优先级,如果优先级较低,则执行栈操作直到满足要求,并将结果入栈 operandStack。
最终,当遍历完整个表达式后,执行栈操作以处理剩余的运算符。最后,从 operandStack 中取出最终的结果即为中缀表达式的求值结果。
请注意,上述示例代码仅提供了一个基本的实现方法,并不能处理包含变量、函数调用、括号嵌套等复杂的表达式。如果需要更全面和强大的表达式求值功能,可能需要借助更复杂的编译原理相关技术。
希望以上信息能够帮助你理解中缀表达式求值的实现过程。如果有进一步的疑问,请随时追问。
球一个最佳答案谢谢啦!这对我非常重要!   |
|