📜  中缀 c 程序的后缀 (1)

📅  最后修改于: 2023-12-03 15:06:15.521000             🧑  作者: Mango

中缀 C 程序的后缀

什么是中缀表达式

中缀表达式是指常见的以运算符在中间的算术表达式,例如 2 + 3 * 4。在计算机中,中缀表达式的处理较为复杂,需要进行运算符优先级的判断和括号的处理。

什么是后缀表达式

后缀表达式,也称为逆波兰表达式,是一种将运算符放在操作数之后的表达式表示方法,例如 2 3 4 * +。在计算机中,后缀表达式的处理比中缀表达式简单,可以直接通过栈来实现运算。

中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式的过程需要使用到栈,具体步骤如下:

  1. 从左到右扫描中缀表达式的每个元素;
  2. 如果扫描到操作数,将其添加到后缀表达式中;
  3. 如果扫描到操作符,从栈顶开始依次弹出比当前操作符优先级高或相等的操作符,并添加到后缀表达式中,直到栈顶操作符优先级比当前操作符低,或者栈顶为左括号,将当前操作符压入栈中;
  4. 如果扫描到左括号,将其压入栈中;
  5. 如果扫描到右括号,从栈顶开始依次弹出操作符并添加到后缀表达式中,直到弹出左括号为止,左括号不添加到后缀表达式中。

转换完毕后,如果栈中还有操作符,依次弹出并添加到后缀表达式中。

后缀表达式的计算

后缀表达式的计算可以用栈来实现。具体步骤如下:

  1. 从左到右扫描后缀表达式的每个元素;
  2. 如果扫描到操作数,将其压入栈中;
  3. 如果扫描到操作符,弹出栈顶的两个操作数进行计算,并将计算结果压入栈中;
  4. 扫描结束后,栈中只剩下一个元素,即为后缀表达式的结果。
示例程序

下面是一个将中缀表达式转换为后缀表达式并计算结果的示例程序(假设中缀表达式中只包含加减乘除和括号):

#include <stdio.h>
#include <stdlib.h>  // 包含 exit 函数
#include <string.h>  // 包含 strchr 函数

#define MAX_SIZE 100  // 定义栈的最大容量

int is_operator(char c);
int precedence(char op);
void infix_to_postfix(char *infix, char *postfix);
int evaluate_postfix(char *postfix);

int main()
{
    char infix[MAX_SIZE];
    char postfix[MAX_SIZE];

    printf("请输入中缀表达式:\n");
    gets(infix);  // 读取中缀表达式

    infix_to_postfix(infix, postfix);  // 转换为后缀表达式

    printf("后缀表达式为:%s\n", postfix);

    int result = evaluate_postfix(postfix);  // 计算后缀表达式的结果

    printf("计算结果为:%d\n", result);

    return 0;
}

int is_operator(char c)
{
    return (c == '+' || c == '-' || c == '*' || c == '/');
}

int precedence(char op)
{
    switch (op) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}

void infix_to_postfix(char *infix, char *postfix)
{
    char stack[MAX_SIZE];  // 定义栈
    int top = -1;  // 栈顶指针
    int i = 0, j = 0;

    while (infix[i] != '\0') {
        if (infix[i] == '(') {
            stack[++top] = infix[i];  // 左括号入栈
        } else if (infix[i] == ')') {
            while (stack[top] != '(') {
                postfix[j++] = stack[top--];  // 弹出操作符并添加到后缀表达式中
            }
            top--;  // 弹出左括号
        } else if (is_operator(infix[i])) {
            while (top >= 0 && precedence(stack[top]) >= precedence(infix[i])) {
                postfix[j++] = stack[top--];  // 弹出优先级高的操作符并添加到后缀表达式中
            }
            stack[++top] = infix[i];  // 当前操作符入栈
        } else {  // 操作数
            postfix[j++] = infix[i];
        }
        i++;
    }

    while (top >= 0) {
        postfix[j++] = stack[top--];  // 弹出栈中剩余的操作符
    }

    postfix[j] = '\0';
}

int evaluate_postfix(char *postfix)
{
    int stack[MAX_SIZE];
    int top = -1;
    int i = 0;

    while (postfix[i] != '\0') {
        if (postfix[i] == '+' || postfix[i] == '-' || postfix[i] == '*' || postfix[i] == '/') {
            int op2 = stack[top--];  // 弹出操作数
            int op1 = stack[top--];
            int result;
            switch (postfix[i]) {
                case '+':
                    result = op1 + op2;
                    break;
                case '-':
                    result = op1 - op2;
                    break;
                case '*':
                    result = op1 * op2;
                    break;
                case '/':
                    result = op1 / op2;
                    break;
            }
            stack[++top] = result;  // 计算结果入栈
        } else {  // 操作数
            int num = strtol(&postfix[i], NULL, 10);  // 将字符串转换为整数
            stack[++top] = num;  // 操作数入栈
            i += strlen(&postfix[i]) - 1;  // 更新 i 的值,跳过数字字符串
        }
        i++;
    }

    return stack[0];
}

这个示例程序只是实现了最基本的功能,如果想要实现更复杂的表达式计算,还需要考虑负数的情况和小数的情况等。