OJ-0918**

题目

在这里插入图片描述
示例1

输入:
1 + 5 * 7 / 8
输出:
43/8

示例2

输入:
1 / (0 - 5)
输出:
-1/5

说明:负号需要提到最前面

示例3

输入:
1 * (3 * 4 / (8 - (7 + 0)))
输出:
12

说明:注意括号可以多重嵌套

解题思路

1.处理空格:首先,去除输入表达式中的空格。
2.转换为逆波兰表达式:利用栈来将中缀表达式转换为逆波兰表达式。这可以通过遍历输入表达式的每个元素来实现。遇到数字直接输出,遇到运算符则比较其优先级与栈顶运算符的优先级,按照一定规则进行出栈和入栈操作。具体规则可以参考算法导论中关于中缀表达式转换为逆波兰表达式的算法。
3.计算逆波兰表达式:利用栈来计算逆波兰表达式。
遍历逆波兰表达式的每个元素,遇到数字则入栈,遇到运算符则从栈中弹出足够的操作数进行运算,再将结果入栈。重复此过程直到表达式结束。
4. 处理分数:在计算过程中,需要考虑分数的表示和简化。可以使用一个结构体或类来表示分数,其中包含分子和分母两个整数。每次运算后,检查结果是否为整数,如果是整数则直接输出,如果是分数则对分数进行化简。
5.异常处理:在计算过程中,需要检查除数是否为0。如果遇到除数为0的情况,直接输出"ERROR"

题解

优化之后:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

/**
 * @Author: 
 * @Create: 2024-10-01 13:51
 * @Description:
 */
public class 给定一个表达式2 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String infix = in.nextLine().replace(" ", "");
        List<String> suffix = changeToSuffix(infix);
        try {
            Num num = calculateSuffix(suffix);
            System.out.println(num.getResult(num));
        } catch (ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }

    private static Num calculateSuffix(List<String> suffix) {
        Stack<Num> nums = new Stack<>();
        Num res = new Num(0, 1);
        for (String s : suffix) {
            if (s.matches("\\d+")) {
                nums.push(new Num(Integer.parseInt(s), 1));
            } else {
                Num num1 = nums.pop();
                Num num2 = nums.pop();
                if ("*".equals(s)) {
                    res = num2.mul(num1);
                } else if ("/".equals(s)) {
                    res = num2.div(num1);
                } else if ("+".equals(s)) {
                    res = num2.add(num1);
                } else if ("-".equals(s)) {
                    res = num2.sub(num1);
                } else {
                    throw new ArithmeticException("运算符有误");
                }
                nums.push(res);
            }
        }
        return res;
    }

    private static List<String> changeToSuffix(String infix) {
        Stack<String> oper = new Stack<>();
        ArrayList<String> res = new ArrayList<>();

        int len = infix.length();
        for (int i = 0; i < len; i++) {
            char c = infix.charAt(i);
            if (Character.isDigit(c)) {
                int j = i;
                while (j < len && Character.isDigit(infix.charAt(j))) {
                    j++;
                }
                res.add(infix.substring(i, j));
                i = --j;
            } else if (c == '(') {
                oper.push(c + "");
            } else if (c == ')') {
                while (!oper.isEmpty() && !"(".equals(oper.peek())) {
                    res.add(oper.pop());
                }
                oper.pop();
            } else {
                while (!oper.isEmpty() && getPriority(c + "") <= getPriority(oper.peek())) {
                    res.add(oper.pop());
                }
                oper.push(c + "");
            }
        }
        while (!oper.isEmpty()) {
            res.add(oper.pop());
        }
        return res;
    }

    private static int getPriority(String operator) {
        if ("*".equals(operator) || "/".equals(operator)) return 2;
        else if ("+".equals(operator) || "-".equals(operator)) return 1;
        else return 0;
    }

    static class Num {
        int x;
        int y;

        public Num(int x, int y) {
            this.x = x;
            this.y = y;
        }

        private Num mul(Num num) {
            return new Num(this.x * num.x, this.y * num.y);
        }

        private Num div(Num num) {
            if (num.x == 0) {
                throw new ArithmeticException("ERROR");
            }
            return new Num(this.x * num.y, this.y * num.x);
        }

        private Num add(Num num) {
            return new Num(this.x * num.y + this.y * num.x, this.y * num.y);
        }

        private Num sub(Num num) {
            return new Num(this.x * num.y - this.y * num.x, this.y * num.y);
        }

        private int gcd(int a, int b) {
            return a % b == 0 ? b : gcd(b, a % b);
        }

        private String getResult(Num num) {
            int xy_gcd = gcd(num.x, num.y);
            int x = num.x / xy_gcd;
            int y = num.y / xy_gcd;
            if (x * y < 0) {
                x = -Math.abs(x);
                y = Math.abs(y);
            }
            return x % y == 0 ? x / y + "" : x + "/" + y;
        }
    }
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String expression = in.nextLine();
        List<String> infixExpressList = toInfixExpressList(expression);
        List<String> suffixExpressionList = parseSuffixExpressionList(infixExpressList);
        try {
            System.out.println(calculate(suffixExpressionList));
        } catch (Exception e) {
            System.out.println("ERROR");
        }
    }

    private static String calculate(List<String> list) {
        Stack<Num> stack = new Stack<>();
        for (String item : list) {
            if (item.matches("\\d+")) {
                stack.push(new Num(Integer.parseInt(item)));
            } else {
                Num num2 = stack.pop();
                Num num1 = stack.pop();
                Num res = new Num(0);
                switch (item) {
                    case "+":
                        add(res, num1, num2);
                        break;
                    case "-":
                        sub(res, num1, num2);
                        break;
                    case "*":
                        multi(res, num1, num2);
                        break;
                    case "/":
                        div(res, num1, num2);
                        break;
                    default:
                        break;
                }
                stack.push(res);
            }
        }
        return getRes(stack.pop());
    }

    private static String getRes(Num res) {
        int x = res.x;
        int y = res.y;
        if (x * y < 0) {
            x = -Math.abs(x);
            y = Math.abs(y);
        }
        return x % y == 0 ? x / y + "" : x + "/" + y;
    }

    private static void div(Num res, Num num1, Num num2) {
        if (num2.x == 0) {
            throw new RuntimeException();
        }
        res.x = num1.x * num2.y;
        res.y = num1.y * num2.x;
        simplify(res);
    }

    private static void multi(Num res, Num num1, Num num2) {
        res.x = num1.x * num2.x;
        res.y = num1.y * num2.y;
        simplify(res);
    }

    private static void add(Num res, Num num1, Num num2) {
        res.x = num1.x * num2.y + num1.y * num2.x;
        res.y = num1.y * num2.y;
        simplify(res);
    }

    private static void sub(Num res, Num num1, Num num2) {
        res.x = num1.x * num2.y - num1.y * num2.x;
        res.y = num1.y * num2.y;
        simplify(res);
    }

    private static void simplify(Num res) {
        int xyGcd = gcd(res.x, res.y);
        res.x /= xyGcd;
        res.y /= xyGcd;
    }

    private static List<String> parseSuffixExpressionList(List<String> list) {
        Stack<String> s1 = new Stack<>();
        List<String> s2 = new ArrayList<>();
        for (String item : list) {
            if (item.matches("\\d+")) {
                s2.add(item);
            } else if (item.equals("(")) {
                s1.push(item);
            } else if (item.equals(")")) {
                while (!s1.peek().equals("(")) {
                    s2.add(s1.pop());
                }
                s1.pop();
            } else { // 运算符
                while (!s1.isEmpty() && getPriority(item) <= getPriority(s1.peek())) {
                    s2.add(s1.pop());
                }
                s1.push(item);
            }
        }
        // s1剩余-->s2
        while (!s1.isEmpty()) {
            s2.add(s1.pop());
        }
        return s2;
    }

    private static List<String> toInfixExpressList(String s) {
        List<String> res = new ArrayList<>();
        int i = 0;
        while (i < s.length()) {
            if (' ' == s.charAt(i)) {
                i++;
            } else if (!Character.isDigit(s.charAt(i))) {
                res.add(s.charAt(i) + "");
                i++;
            } else {
                StringBuilder str = new StringBuilder();
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    str.append(s.charAt(i));
                    i++;
                }
                res.add(str.toString());
            }
        }
        return res;
    }

    // 最大公约数
    public static int gcd(int a, int b) {
        return (a % b == 0) ? b : gcd(b, a % b);
    }

    public static int getPriority(String input) {
        if (input.equals("*") || input.equals("/")) {
            return 2;
        } else if (input.equals("+") || input.equals("-")) {
            return 1;
        } else {
            return 0;
        }
    }

    static class Num {
        int x;
        int y = 1;

        public Num(int x) {
            this.x = x;
        }
    }
}

参考

存在问题

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

public class 给定一个表达式 {
    public static Stack<Integer[]> nums;
    public static Stack<Character> operations;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String input_str1 = in.nextLine();
        nums = new Stack<>();
        operations = new Stack<>();
        int length = input_str1.length();
        char[] input_str = input_str1.toCharArray();

        String current = "";
        int i = 0;
        while (i < length) {
            if (Character.isDigit(input_str[i])) {
                while (true) {
                    if (!Character.isDigit(input_str[i])) {
                        break;
                    }
                    current += input_str[i];
                    if (i + 1 >= length) {
                        break;
                    }
                    i += 1;
                }
                nums.push(new Integer[]{1, Integer.parseInt(current)});
                current = "";
            } else if (input_str[i] == '(') {
                operations.push(input_str[i]);
            } else if (input_str[i] == ')') {
                while (operations.peek() != '(') {
                    eval();
                }
                operations.pop();
            } else if (input_str[i] == ' ') {
                i += 1;
                continue;
            } else {
                while (!operations.isEmpty() && operations.peek() != '('
                        && get_priority(input_str[i]) <= get_priority(operations.peek())) {
                    eval();
                }
                operations.push(input_str[i]);
            }

            i++;
        }

        while (true) {
            if (nums.size() <= 1) {
                break;
            } else {
                eval();
            }
        }

        Integer[] result = nums.peek();
        if (result[0] == 0) {
            System.out.println("ERROR");
        } else {
            int up = gcd(result[0], result[1]);
            result[0] /= up;
            result[1] /= up;
            if (result[0] * result[1] < 0) {
                System.out.print("-");
            }
            if (Math.abs(result[0]) == 1) {
                System.out.println(result[1]);
            } else {
                System.out.println(Math.abs(result[1]) + "/" + Math.abs(result[0]));
            }
        }
    }

    // 最大公约数
    public static int gcd(int a, int b) {
        return (a % b == 0) ? b : gcd(b, a % b);
    }

    public static void eval() {
        Integer[] nums1 = nums.pop();
        Integer[] nums2 = nums.pop();
        char x = operations.pop();
        Integer[] result = new Integer[2];

        if (x == '*' || x == '+' || x == '-') {
            result[0] = nums2[0] * nums1[0];
        } else {
            result[0] = nums2[0] * nums1[1];
        }

        int sum_a = nums2[1] * nums1[0];
        int sum_b = nums1[1] * nums2[0];
        if (x == '*') {
            result[1] = nums2[1] * nums1[1];
        } else if (x == '+') {
            result[1] = sum_a + sum_b;
        } else if (x == '-') {
            result[1] = sum_a - sum_b;
        } else {
            result[1] = nums2[1] * nums1[0];
        }
        nums.push(result);
    }

    public static int[] split(String input_str, String chars) {
        String[] tmp2 = input_str.split(chars);
        int[] results = new int[tmp2.length];
        for (int i = 0; i < tmp2.length; i++) {
            results[i] = Integer.parseInt(tmp2[i]);
        }
        return results;
    }

    public static int get_priority(Character input) {
        if (input == '+' || input == '-') {
            return 0;
        } else {
            return 1;
        }
    }
}
SDUT-OJ(Software Development University of Tsinghua Online Judge)是一个在线编程平台,提供给清华大学软件学院的学生和爱好者练习和解决算法问题的环境,其中包括各种计算机科学题目,包括数据结构、算法、图形等。对于"最小生成树"(Minimum Spanning Tree, MST)问题,它是图论中的经典问题,目标是从一个加权无向图中找到一棵包含所有顶点的树,使得树的所有边的权重之和最小。 在C语言中,最常见的是使用Prim算法或Kruskal算法解最小生成树。Prim算法从一个顶点开始,逐步添加与当前生成树相连且权重最小的边,直到所有顶点都被包含;而Kruskal算法则是从小到大对所有边排序,每次选取没有形成环的新边加入到树中。 如果你想了解如何用C语言实现这些算法,这里简单概括一下: - 通常使用优先队列(堆)来存储边和它们的权重,以便快速查找最小值。 - 从任意一个顶点开始,遍历与其相邻的边,若新边不形成环,就更新树,并将新边加入优先队列。 - Kruskal算法: - 先将所有的边按照权重升序排序。 - 创建一个空的最小生成树,然后依次取出排序后的边,如果这条边连接的两个顶点不在同一个连通分量,则将其添加到树中。 如果你需要更详细的代码示例,或者有具体的问题想了解(比如如何处理环、如何实现优先队列等),请告诉我,我会为你提供相应的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值