CCF-CSP-201903-2-二十四点 JAVA

6 篇文章 0 订阅

在这里插入图片描述在这里插入图片描述
提交结果:
在这里插入图片描述

难点:计算一条 考虑加减乘除优先级的 字符串算式

代码:

import java.util.Scanner;
import java.util.Stack;

public class 二十四点 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        StringBuffer SB = new StringBuffer();

        // 录入要运算的算式个数
        int n = input.nextInt();

        // 以 "Yes"或"No"的字符串 储存算式运算是否是24点
        String[] res = new String[n];

        // 写入StringBuffer的字符串
        String appendStr;

        // 录入n条算式
        for (int i = 0; i < n; i++) {
            appendStr = input.next(); // 算式
            SB.append(appendStr); // 算式写入StringBuffer
            res[i] = is24(SB); // 将判断结果写入res数组
            SB.delete(0, SB.length()); // 将StringBuffer重置为空
        }

        // 输出结果
        for (int i = 0; i < n; i++) {
            System.out.println(res[i]);
        }

    }


    /*
    *  判断是否是24点
    *   true  ->  return "Yes"
    *   false ->  return "No"
    * */
    static String is24(StringBuffer SB) {
        Stack<Integer> numStack = new Stack(); // 数栈
        Stack<Character> symbolStack = new Stack(); // 运算符号栈
        int item; // 在StringBuffer中读出的字符

        int num1; // 在数栈弹出的num1 用于运算
        int num2; // 在数栈弹出的num2 用于运算
        int symbol; // 在栈中读出的运算符号
        int res = 0; // num1 num2 symbol的运算结果

        int priority1; // 即将入栈符号的优先级
        int priority2; // 符号栈中读出的符号的优先级

        // 循环将数据从 字符串 -> (处理) -> 栈
        for (int i = 0; i < SB.length(); i++) {
            item = SB.charAt(i);

            priority1 = symbolPriority(item);
            // 如果是数字
            if (priority1 == -1) {
                item -= 48;
                // 入数栈
                numStack.add(item);
            }
            // 如果是符号
            else {

                // 如果栈空 则不采取本轮操作  直接执行if后面的入栈操作
                if (!symbolStack.isEmpty()) {
                    // 在符号栈中读出一个字符 与即将入栈的符号比较优先级
                    symbol = symbolStack.peek();

                    // 栈中读出字符的优先级
                    priority2 = symbolPriority(symbol);

                    // 如果即将入栈的符号优先级 小于或等于 符号栈栈顶的符号优先级  则执行运算
                    if (priority1 <= priority2) {
                        // 从数栈中读出两个数
                        num1 = numStack.pop();
                        num2 = numStack.pop();

                        // 从符号栈弹出一个符号  注意peek是读出  pop是弹出
                        symbol = symbolStack.pop();

                        // 根据读出的符号和数字进行运算
                        res = getSymbol2Num(symbol, num1, num2);

                        // 将运算结果入数栈
                        numStack.add(res);

                    }
                }

                // 即将入符号栈的字符 入栈
                symbolStack.add((char) item);

            }
        }

        // 将栈中剩余数据处理
        while (numStack.size() > 1) {
            // 从数栈中读出两个数
            num1 = numStack.pop();
            num2 = numStack.pop();

            // 从符号栈弹出一个符号
            symbol = symbolStack.pop();

            // 根据读出的符号和数字进行运算
            res = getSymbol2Num(symbol, num1, num2);

            // 将运算结果入数栈
            numStack.add(res);
        }

        // 将数栈中最后一个元素取出 作为结果
        res = numStack.pop();

        // 如果是24点 返回Yes   否则 返回No
        if (res == 24) {
            return "Yes";
        } else {
            return "No";
        }
    }

    /*
    *  用数字判断读取的字符类型
    *  乘除 1
    *  加减 0
    *  数字 -1
    */
    static int symbolPriority(int symbol) {
        switch (symbol) {
            case 'x':
            case '/':
                return 1; // 乘除
            case '+':
            case '-':
                return 0; // 加减
            default:
                return -1; // 数字
        }
    }

    // (两个数 + 符号)进行加减乘除运算
    static int getSymbol2Num(int symbol, int num1, int num2) {
        switch (symbol) {
            case 'x':
                return num2 * num1;
            case '/':
                return num2 / num1;
            case '+':
                return num2 + num1;
            case '-':
                return num2 - num1;
            default:
                return 0;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值