题解 | #矩阵乘法计算量估算# 编译原理:语法归约

矩阵乘法计算量估算

https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b

看到这种若干个符号合并为一个符号的操作就想到了编译原理的语法归约操作,条件反射了属于是。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 有点类似编译原理中对语法的归约处理
        while (in.hasNextInt()) {
            int n = in.nextInt();
            // 这里暂时记录输入的行和列
            List<int[]> list = new ArrayList<>(n);
            for (int i = 0; i < n; i++) {
                list.add(new int[]{in.nextInt(), in.nextInt()});
            }

            String expr = in.next();
            Deque<Node> stack = new ArrayDeque<>();
            int sum = 0;
            for (char ch : expr.toCharArray()) {
                switch (ch) {
                    case '(':
                        stack.push(Node.LEFT);
                        break;
                    case ')': {
                        // 输入右括号,不断弹出符号,直到弹出左括号,将它们记录到 nodeList 中
                        Deque<Node> nodeList = new ArrayDeque<>();
                        while (stack.peek() != Node.LEFT) {
                            Node pop = stack.pop();
                            nodeList.addFirst(pop);
                        }
                        // 弹出左括号
                        stack.pop();
                        // 从左到右,每次计算两个矩阵的乘积,消除两个矩阵,得到新的矩阵
                        // 新矩阵的行数和第一个矩阵相同,列数和第二个矩阵相同
                        while (nodeList.size() > 1) {
                            Node first = nodeList.removeFirst();
                            Node second = nodeList.removeFirst();
                            sum += first.row * first.col * second.col;
                            nodeList.addFirst(new Node(first.name + second.name, first.row, second.col));
                        }
                        // 合并后剩下的矩阵重新添加到栈中
                        Node node = nodeList.removeFirst();
                        stack.push(node);
                        break;
                    }
                    default:
                        // 添加矩阵到栈中
                        stack.push(new Node(ch + "", list.get(ch - 'A')[0], list.get(ch - 'A')[1]));
                }
            }
            System.out.println(sum);
        }
    }

    public static class Node {
        // 左括号
        static final Node LEFT = new Node("(", -1, -1);

        String name;
        int row;
        int col;

        public Node(String name, int row, int col) {
            this.name = name;
            this.row = row;
            this.col = col;
        }
    }
}

全部评论

相关推荐

少年郎as:这不把公司名贴出来那我可要喷你了哦
点赞 评论 收藏
分享
bg27强双非本,目前在学习golang后端gin框架部分,在b站找了一个轮子项目敲了一下,技术栈是gin&nbsp;+&nbsp;gorm&nbsp;+&nbsp;mysql&nbsp;+&nbsp;redis。我目前的想法是这一个月学习408和go八股以及刷算法然后在12月找个寒假实习然后大三下开始准备考研。我是考研意愿比较强烈,想问一下我是应该all&nbsp;in其中一个方向吗,我感觉我实习对我考研来说也是没什么帮助的好像。
牛客28967172...:毕业工作,考研,考公是完全不同的方向。 99%的人拼尽全力也只能把一个做好(能做好都已经是佼佼者了,比如进进大厂,考985或者考公) 如果你确定要考研可以不用学任何就业技术框架,也不用实习经验,刷题背知识点就行,但注意必须考92院校起步,因为这个年代双非硕毕业后完全不如双非本(互联网行业),可以说双非硕在互联网就业完全是负收益
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务