【计算机如何计算布尔/算术表达式】中缀表达式转后缀表达式 计算算式值

 

 

 

 


//input:A*(B+C)-d/(e+f)  output:[A, B, C, +, *, d, e, f, +, /, -]
public class Pro2 {
    public static Stack<Character> s1 = new Stack<>();
    public static Stack<Character> s2 = new Stack<>();
    public static void gotOper(char opThis, int prec1) {
        // 如果s1为空,则直接将当前解析的运算符压入s1
        if(s1.isEmpty()) {
            s1.push(opThis);
            return;
        }
        while (!s1.isEmpty()) {
            char opTop = s1.peek();
            if (opTop == '(') {// 如果栈顶是'(',直接将操作符压入s1
                //s1.push(opThis);
                break;
            } else {
                int prec2;
                if (opTop == '+' || opTop == '-') {
                    prec2 = 1;
                } else {
                    prec2 = 2;
                }
                if (prec2 < prec1) {// 如果当前运算符比s1栈顶运算符优先级高,则将运算符压入s1
                    //s1.push(opThis);
                    break;
                } else {// 如果当前运算符与栈顶运算符相同或者小于优先级别,那么将S1栈顶的运算符弹出并压入到S2中
                    // 并且要再次再次转到while循环中与 s1 中新的栈顶运算符相比较;
                    opTop=s1.pop();
                    s2.push(opTop);
                }
            }

        }// end while
        s1.push(opThis);
    }

    // 当前字符是 ')' 时,如果栈顶是'(',则将这一对括号丢弃,否则依次弹出s1栈顶的字符,压入s2,直到遇到'('
    public static void gotParen(char ch) {
        while (!s1.isEmpty()) {
            char chx = s1.pop();
            if (chx == '(') {
                break;
            } else {
                s2.push(chx);
            }
        }
    }
    // 中缀表达式转换为后缀表达式,将结果存储在栈中返回,逆序显示即后缀表达式
    public static void InfixToSuffix(String input) {
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            System.out.println("当前解析的字符:" + ch);

            switch (ch) {
                case '+':
                case '-':
                    gotOper(ch, 1);
                    break;
                case '*':
                case '/':
                    gotOper(ch, 2);
                    break;
                case '(':
                    s1.push(ch);// 如果当前字符是'(',则将其入栈
                    break;
                case ')':
                    gotParen(ch);
                    break;
                default:
                    // 如果当前解析的字符是操作数,则直接压入s2
                    s2.push(ch);
                    break;
            }// end switch
            System.out.println(s1);
            System.out.println(s2);
        }
        while (!s1.isEmpty()) {
            s2.push(s1.pop());
        }
        return;
    }
    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("input.txt");
        FileInputStream fileinputStream = new FileInputStream(file);
        System.setIn(fileinputStream);

        Scanner in = new Scanner(System.in);

        String inputStr = in.nextLine();
        System.out.println(inputStr.length());
        InfixToSuffix(inputStr);
        System.out.println(s2);
    }
    
}

从优先级角度讲,存储运算符的栈是一个单增栈,如果想入栈的优先级比栈顶小,则把栈顶运算符弹出压入到结果栈

https://zhuanlan.zhihu.com/p/37467928(有比较详细的图说明)

 

//计算逻辑表达式的值,表达式由以下字符租场 T F && || ! () 返回逻辑表达式的结果 T或者F,优先级为 ()>!>&&>||
/*
T || F && F || F
!F || T && T
T && F
T
T
F*/

//input:A*(B+C)-d/(e+f)  output:[A, B, C, +, *, d, e, f, +, /, -]
public class Pro2 {
    public static Stack<Character> s1 = new Stack<>();
    public static Stack<Character> s2 = new Stack<>();
    public static char[] pre = new char[1000];
    public static void gotOper(char opThis, int prec1) {
        // 如果s1为空,则直接将当前解析的运算符压入s1
        if(s1.isEmpty()) {
            s1.push(opThis);
            return;
        }
        while (!s1.isEmpty()) {
            char opTop = s1.peek();
            if (opTop == '(') {// 如果栈顶是'(',直接将操作符压入s1
                //s1.push(opThis);
                break;
            } else {
                int prec2;
//                if (opTop == '+' || opTop == '-') {
//                    prec2 = 1;
//                } else {
//                    prec2 = 2;
//                }
                prec2=pre[opTop];
                if (prec2 < prec1) {// 如果当前运算符比s1栈顶运算符优先级高,则将运算符压入s1
                    //s1.push(opThis);
                    break;
                } else {// 如果当前运算符与栈顶运算符相同或者小于优先级别,那么将S1栈顶的运算符弹出并压入到S2中
                    // 并且要再次再次转到while循环中与 s1 中新的栈顶运算符相比较;
                    opTop=s1.pop();
                    s2.push(opTop);
                }
            }

        }// end while
        s1.push(opThis);
    }

    // 当前字符是 ')' 时,如果栈顶是'(',则将这一对括号丢弃,否则依次弹出s1栈顶的字符,压入s2,直到遇到'('
    public static void gotParen(char ch) {
        while (!s1.isEmpty()) {
            char chx = s1.pop();
            if (chx == '(') {
                break;
            } else {
                s2.push(chx);
            }
        }
    }
    // 中缀表达式转换为后缀表达式,将结果存储在栈中返回,逆序显示即后缀表达式
    public static void InfixToSuffix(String input) {
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            System.out.println("当前解析的字符:" + ch);
            if(ch==' ') continue;
            if(ch=='|' && input.charAt((i-1))=='|') continue;
            if(ch=='&' && input.charAt((i-1))=='&') continue;
            switch (ch) {
                case '|':
                    gotOper(ch, 1);
                    break;
                case '&':
                    gotOper(ch, 2);
                    break;
                case '!':
                    gotOper(ch, 3);
                    break;
                case '(':
                    s1.push(ch);// 如果当前字符是'(',则将其入栈
                    break;
                case ')':
                    gotParen(ch);
                    break;
                default:
                    // 如果当前解析的字符是操作数,则直接压入s2
                    s2.push(ch);
                    break;
            }// end switch
            System.out.println(s1);
            System.out.println(s2);
        }
        while (!s1.isEmpty()) {
            s2.push(s1.pop());
        }
        return;
    }
    public static void  parseSuffix(){
        String s = s2.toString();
        System.out.println(s); // [F, !, T, T, &, |]
        //Stack<Character> stchar = new Stack<>();
        Stack<Character> stNum = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char curc = s.charAt(i);
            if(curc==' '|| curc==',' || curc=='[') continue;
            if(curc=='T' || curc=='F') stNum.push(curc);
            else {
                if(curc=='!') {
                    char topc = stNum.pop();
                    if(topc=='T') stNum.push('F');
                    else stNum.push('T');
                }else if(curc=='|'){
                    char topc=stNum.pop();
                    char top2c=stNum.pop();
                    if(topc=='T' || top2c=='T'){
                        stNum.push('T');
                    }else stNum.push('F');

                }else if(curc=='&'){
                    char topc=stNum.pop();
                    char top2c=stNum.pop();
                    if(topc=='F' || top2c=='F'){
                        stNum.push('F');
                    }else stNum.push('T');
                }
            }
        }
        System.out.println("result:");
        System.out.println(stNum);
    }
    public static void main(String[] args) throws FileNotFoundException {
        File file = new File("input.txt");
        FileInputStream fileinputStream = new FileInputStream(file);
        System.setIn(fileinputStream);

        Scanner in = new Scanner(System.in);

        pre['!']=3;
        pre['&']=2;
        pre['|']=1;


        String inputStr = in.nextLine();
        System.out.println(inputStr.length());
        InfixToSuffix(inputStr);
        System.out.println(s2);
        System.out.println("+++++++++++++++++++++++++++++++++++");
        parseSuffix();
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值