中缀转前缀(全网最详细)

概念

  • 什么是前缀表达式?
    • 前缀表达式,其实就是一个中缀表达式 AOB => OAB (A、B是式子、O 为运算符),将运算符向前放

中缀转前缀举例

  • 中缀表达式:(a + b)* c - (d / c)
    • 第一步:根据运算规则(从左至右,优先级高优先),先去计算 a + b ,此时 A = a B = b O = +,中转前 AOB=>OAB=>+ab
    • 第二步:根据运算规则,接下来去计算 (+ab) * c ,此时 A = +ab B = c O = *, 中转前 AOB=>OAB=>*+abc
    • 第三步:根据运算规则,接下来去计算 d / c,此时 A = d B = c O = /,中转前 AOB=>OAB=> /dc
    • 第四步:根据运算规则,接下来去计算 (*+abc) - (/dc) , 此时 A = *+abc B = /dc O = -,中转前AOB=>OAB=> -*+abc /dc
  • 后缀表达式即是: -*+abc /dc

综上,我们可以看出,其实中缀转前缀,就是根据运算规则,找到我们表达式中最先计算的两项和运算符,然后,将其运算符放前边,并且要保持 A 和 B 的相对顺序不变,依次执行,直到转化成前缀表达式

中缀转前缀过程

详细规则:

  • 初始化一个栈,存储 运算符
  • 从右到左扫描(依次前放字符
    1. 遇到操作数。直接加入前缀表达式
    2. 遇到界限符。遇到 “)” 直接入栈,遇到 “(” 则依次弹出栈内运算符并加入前缀表达式,直到弹出 “)” 为止 注意:“( )” 不加入前缀表达式
    3. 遇到运算符。依次弹出栈中优先级高于当前运算符的所有运算符,并加入前缀表达式,若碰到 “)” 或 栈空则停止。之后再把当前运算符入栈。
    4. 处理完所有字符后,将栈中剩余运算符依次弹出,并加入前缀表达式

注意:

​ ①:中转前是依次 将字符 前放,中转后是依次将字符 后放

​ ②:遇到运算符,中转前是 将栈中优先级高的弹出 。中转后是 将栈中优先级高于和等于的弹出

详细执行过程:

中缀转前缀(全网最详细)_第1张图片

Code

#include 
#include 
#include 

#define MAX_SIZE 100

// 运算符优先级函数
int precedence(char op) {
    if (op == '+' || op == '-') {
        return 1;
    } else if (op == '*' || op == '/') {
        return 2;
    } else {
        return 0;
    }
}

// 中缀转前缀实现
void infix_to_prefix(char* infix, char* prefix) {
    char stack[MAX_SIZE];						// 定义一个栈,用来存放 运算符
    int top = -1;								// 定义 栈顶指针
    int i, j , temp , k=0;
    
    // 遍历到最后一个字符,k 最后指向 '\0' 的位置
    while(infix[k] != '\0'){
        ++k;
    } 
    
    // 从右至左遍历中缀字符数组
    for (i = k-1, j = 0; i >= 0; --i) {
        // 判断,如果是字符,将其存入前缀字符数组中
        if (infix[i] >= 'a' && infix[i] <= 'z') {
            prefix[j++] = infix[i];
        } else if (infix[i] == ')') {				// 如果是 右括号,直接放入栈中
            stack[++top] = infix[i];	
        } else if (infix[i] == '(') {				// 如果是 左括号
            // 将栈中 右括号之前的 运算符依次弹出,并进入前缀数组中
            while (top != -1 && stack[top] != ')') {
                prefix[j++] = stack[top--];
            }
            // 再减一次是为了:弹出 右括号
            top--; 
        } else {
            // 栈不空,并且当栈顶运算符优先级 大于 扫描到中缀运算符优先级,将栈中元素依次弹出,放入前缀数组中
            while (top != -1 && precedence(stack[top]) > precedence(infix[i])) {
                prefix[j++] = stack[top--];
            }
            // 再将扫描到的中缀运算符,放入栈中
            stack[++top] = infix[i];
        }
    }
    
    // 当扫描完后,将栈中元素依次弹出,并放入前缀表达式数组中
    while (top != -1) {
        prefix[j++] = stack[top--];
    }
    
    // 进行逆置 
    for(i = 0, k = j-1; i < k; ++i,--k){
    	temp = prefix[i];
    	prefix[i] = prefix[k];
    	prefix[k] = temp;
	}
    
    // 设置字符数组结束符
    prefix[j] = '\0';
}

int main() {
    char infix[MAX_SIZE];
    char prefix[MAX_SIZE];
    
    printf("输入中缀表达式: ");
    scanf("%s", infix);
    
    infix_to_prefix(infix, prefix);
    
    printf("前缀表达式是: %s\n", prefix);
    
    return 0;
}

中缀转前缀(全网最详细)_第2张图片


中缀转后缀,大家可以参考下这篇文章,点击链接即可!

你可能感兴趣的:(数据结构,算法,数据结构)