首页 > 试题广场 >

矩阵乘法计算量估算

[编程题]矩阵乘法计算量估算
  • 热度指数:77080 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:

A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数。

数据范围:矩阵个数:,行列数:保证给出的字符串表示的计算顺序唯一
进阶:时间复杂度:,空间复杂度:



输入描述:

输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
计算的法则为一个字符串,仅由左右括号和大写字母('A'~'Z')组成,保证括号是匹配的且输入合法!



输出描述:

输出需要进行的乘法次数

示例1

输入

3
50 10
10 20
20 5
(A(BC))

输出

3500
import java.util.Scanner; 
import java.util.HashMap;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int count = 0;
        // 这个哈希表保存了一个(字母,数组)对,分别表示矩阵名称和行列数
        HashMap<Character, int[]> mats = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int[] m = new int[2];
            for (int j = 0; j < 2; j++) {
                m[j] = in.nextInt();
            }
            mats.put((char)(i+65), m);
        }
        String exp = in.next();
        ArrayList<Character> stack = new ArrayList<>();
        for (char c : exp.toCharArray()) {
            String min = "";
            if (c == ')') {
                while (stack.get(stack.size()-1) != '(') {
                    min += stack.remove(stack.size()-1);
                }
                stack.remove(stack.size()-1);  // 消除括号
                int[] temp = compute(mats, min);
                count += temp[0] * temp[1] * temp[2];
                mats.remove(min.charAt(0));
                mats.remove(min.charAt(1));    // 删除旧矩阵
                int[] cu = {temp[2], temp[0]};  // 新矩阵的行列
                mats.put(min.charAt(0), cu);  // 给计算后的新矩阵重新命名
                stack.add(min.charAt(0));  // 再正常入栈
            } else {  // 正常入栈
                stack.add(c);
            }
        }
        System.out.print(count);
    }

    public static int[] compute(HashMap<Character, int[]> mats, String exp) {
        int[] r = {mats.get(exp.charAt(0))[1], mats.get(exp.charAt(0))[0],
                    mats.get(exp.charAt(1))[0]};
        return r;
    }
}
发表于 2024-10-02 11:45:59 回复(0)
反对很多人的做法, 都是错的, 没有考虑ABCDEF没有括号从左到右的顺序
贴上本大神的代码
 import java.util.Scanner; import java.util.Stack; public class Main { public static void main(String[] args)
    { Stack<int[]> stack = new Stack<>(); Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] arr = new int[n][2]; for (int i = 0; i < n; i++)
        { for (int j = 0; j < 2; j++)
            { arr[i][j] = sc.nextInt();
            }
        } String str = sc.next(); //------------------------------------------------------------------   // ,,结果  int[] res = new int[]{0, 0, 0}; int[] tmp; for (int i = 0; i < str.length(); i++)
        { char ch = str.charAt(i); if (ch == '(')
            { //如果res被压栈, 但是又遇到 (  (A(((BC)D)E))         (A(( if (res[2] == 0 && res[0] == 0 && res[1] == 0)
                { stack.push(new int[]{-1, -1, -1});
                } //stack里存储的是引用数据类型, 所以进栈前必须new新的空间, 否则tmp永远等于res  else  { tmp = new int[]{res[0], res[1], res[2]}; stack.push(tmp); res[0] = res[1] = res[2] = 0;
                }
            }//(A(BC))  else if (ch == ')' && !stack.isEmpty())
            { tmp = stack.pop(); if(tmp[0] != -1)
                { res[2] = tmp[0] * tmp[1] * res[1] + tmp[2] + res[2]; res[0] = tmp[0];
                }
            } //必须加这个条件, 否则, ch == ')' && stack.isEmpty()时执行这个条件会数组越界错误  else if (ch >= 'A' && ch <= 'Z')
            { int index = ch - 'A'; //如果是第一个数据, 或数据已经被压栈  if (res[2] == 0 && res[0] == 0 && res[1] == 0)
                { res[0] = arr[index][0]; res[1] = arr[index][1];
                } else  { res[2] += res[0] * res[1] * arr[index][1]; res[1] = arr[index][1];
                }
            }
        } System.out.println(res[2]);
    }
}

发表于 2024-09-18 12:23:10 回复(0)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            int count = in.nextInt();
            List<int[]> list = new ArrayList<>();
            for (int i = 0 ; i < count ; i ++) {
                list.add(new int[] {in.nextInt(), in.nextInt()});
            }
            String algorithm = in.next();

            Stack<int[]> num = new Stack<>();
            Stack<Character> symbol = new Stack<>();
            int sum = 0 ;
            int m = 0;
            for (int i = 0 ; i < algorithm.length() ; i ++) {

                if (algorithm.charAt(i) == '(') {
                    symbol.push('(');
                } else if (algorithm.charAt(i) == ')') {
                    if(num.size()>=symbol.size()){
                        sum += cals(num,symbol);
                    }
                    symbol.pop();
                } else {
                    num.push(list.get(m++));
                    int charIndex = i - 1;
                    while (charIndex >= 0 && algorithm.charAt(charIndex) != '(' &&
                            algorithm.charAt(charIndex) != ')') {
                        charIndex--;
                        sum += cals(num, symbol);
                    }
                }
            }
            while (!symbol.isEmpty() && num.size() > 1) {
                sum += cals(num, symbol);
            }
            System.out.println(sum);
        }
    }
    public static int cals(Stack<int[]> num, Stack<Character> opts) {
        if (num.isEmpty() || num.size() < 2) {
            return 0;
        }
        if (opts.isEmpty()) {
            return 0;
        }
        int[] b = num.pop(), a = num.pop();
        num.push(new int[] {a[0], b[1]});  
        return  b[0] * a[0] * b[1];
    }
}

发表于 2024-09-10 02:19:18 回复(0)
import java.util.Scanner;
import java.util.Stack;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            int[][] arr = new int[n][2];
            for (int i=0;i<n;i++){
                arr[i][0]=scanner.nextInt();
                arr[i][1]=scanner.nextInt();
            }
            scanner.nextLine();
            String str = scanner.nextLine();
            System.out.println(timesOfMatrixMultiplication(str, arr));
        }
    }
    private static int timesOfMatrixMultiplication(String str, int[][] arr) {
        int count = 0;
        int total = 0;
        Stack<Integer> stack = new Stack<Integer>();
        for (char c : str.toCharArray()) {
            if (c == '('){
                count++;
            }else if (c == ')'){
                count--;
                int x = stack.pop();
                int y = stack.pop();
                total +=arr[y][0]*arr[y][1]*arr[x][1] ;
                arr[y][1]=arr[x][1];
                stack.add(y);
            }else{
                int i = c-'A';
                stack.add(i);
            }
        }

        return total;
    }
}


编辑于 2024-04-10 21:51:54 回复(0)
import java.util.Scanner;
import java.util.Stack;

public class Main {
    private static class Matrix {

        int x;
        int y;

        public static Matrix multi(Matrix a, Matrix b) {
            int x = a.x;
            int y = b.y;
            return new Matrix(x, y);

        }

        public static int sum(Matrix a, Matrix b) {
            //System.out.println(a.x + "*" + a.y + "*" + b.y);
            return a.x * a.y * b.y;
        }

        public Matrix(int x, int y) {

            this.x = x;
            this.y = y;
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();//3
        in.nextLine();
        int[][] s = new int[n][2];//二维数组
        for (int i = 0; i < n; i++) {
            s[i][0] = in.nextInt();
            s[i][1] = in.nextInt();
            in.nextLine();//读换行符
        }
        char[] b = in.nextLine().toCharArray();//字符串
        String ns = "";
        //进行字符串运算
        Stack<Matrix> stack = new Stack<Matrix>();
        int sum = 0;
        for (int i = 0; i < b.length; i++) {
            if (b[i] >= 'A' && b[i] <= 'Z') {
                stack.push(new Matrix(s[b[i] - 'A'][0], s[b[i] - 'A'][1]));
            } else if (b[i] == ')') {
                Matrix m1 = stack.pop();
                Matrix m2 = stack.pop();
                //运算
                sum = sum + Matrix.sum(m2, m1);

                stack.push(Matrix.multi(m2, m1));
            }
        }
        System.out.println(sum);

    }
}

思路如下:
1.用一个3行2列的数组记录如下信息
50 10
10 20
20 5
然后开始访问(A(BC)),访问规则是遇到字母入栈,遇到右括号出栈两个,比如遇到第一个右括号出栈的是C,B设为M1,M2,记得运算顺序是M2*M1,生成的结果入栈

然后这里定义了一个矩阵mitrix的类,x表示行,y表示列。同时定义了矩阵的乘法获取新的矩阵行列,以及计算乘法次数的方法。再遍历的过程中就得到了最终结果sum.

有疑问的可以评论,我会解答。也欢迎优化,我写的代码容易理解但是性能差



发表于 2024-03-27 14:17:30 回复(0)
使用HashMap和栈可以很方便
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int matrixNum = in.nextInt();
        Map<Character, int[]> matrixRowColMap = new HashMap<>();
        for (int i = 0; i < matrixNum; i++) {
            int row = in.nextInt();
            int col = in.nextInt();
            matrixRowColMap.put((char) ('A' + i), new int[]{row, col});
        }
        in.nextLine();
        String exp = in.nextLine();
        Stack<Character> calcStack = new Stack<>();
        int calcCnt = 0;
        for (int i = 0; i < exp.length(); i++) {
            if(exp.charAt(i) != ')') {
                calcStack.push(exp.charAt(i));
            } else {
                Character o2 = calcStack.pop();//pop B
                Character o1 = calcStack.pop();//pop A
                calcStack.pop();//pop (
                int[] o1Mat = matrixRowColMap.get(o1);
                int[] o2Mat = matrixRowColMap.get(o2);
                calcCnt += (o1Mat[0] * o2Mat[1] * o2Mat[0]);//乘法次数为i*j*k
                matrixRowColMap.put(o1, new int[]{o1Mat[0], o2Mat[1]});//A=(AB)
                calcStack.push(o1);
            }
        }
        System.out.println(calcCnt);
    }
}


发表于 2024-02-08 17:04:06 回复(1)
定义一个class Matrix,存储左括号 OR 矩阵的 X,Y。使用stack处理,和四则运算类似的思想
import java.util.*;

public class Main {
    static class Matrix{
        boolean isMatrix;
        int x;
        int y;
        public Matrix(){
            isMatrix=false;
        }
        public Matrix(int x,int y){
            this.x=x;
            this.y=y;
            isMatrix=true;
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        Matrix[] matrices=new Matrix[n];
        for(int i=0;i<n;i++){
            matrices[i]=new Matrix(in.nextInt(),in.nextInt());
        }
        in.nextLine();
        char[] rule=in.nextLine().toCharArray();
        int result=0;
        //System.out.println(rule);
        Deque<Matrix> deque=new ArrayDeque<>();
        for(int i=0;i<rule.length;i++){//如rule里,ABC...Z按顺序排列
            if(rule[i]=='('){
                deque.offerLast(new Matrix());
            }else if(rule[i]==')'){ 
                Matrix B=deque.pollLast();
                deque.pollLast();
                if(!deque.isEmpty()){
                    if(deque.peekLast().isMatrix){
                        Matrix A=deque.pollLast();
                        result+=getTimes(A,B);
                        deque.offerLast(new Matrix(A.x,B.y));
                    }else{
                        deque.offerLast(B);
                    }
                }
                //
            }else{
                if(deque.isEmpty()||!deque.peekLast().isMatrix){
                    deque.offerLast(matrices[rule[i]-'A']);
                }else if(deque.peekLast().isMatrix){
                    Matrix A=deque.pollLast();
                    Matrix B=matrices[rule[i]-'A'];
                    result+=getTimes(A,B);
                    deque.offerLast(new Matrix(A.x,B.y));
                }
            }
        }
        System.out.println(result);
    }

    private static int getTimes(Matrix A,Matrix B){
        return A.x*A.y*B.y;
    }
}


发表于 2023-09-08 21:50:56 回复(0)
不需要用到栈啊,运算符又没有优先级
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        in.nextLine();
        Matrix[]  matrixs = new Matrix[n];
        for (int i = 0; i < n; i++) {
            String[] ss = in.nextLine().split(" ");
            Matrix m = new Matrix(Integer.parseInt(ss[0]), Integer.parseInt(ss[1]));
            matrixs[i] = m;
        }
        String expr = in.nextLine();
        // 表达式算法 采用递归dfs来计算,并汇总乘法次数
        dfs(matrixs, expr);
        System.out.println(num);
    }

    private static int num = 0;
    static Matrix dfs(Matrix[] ms, String expr) {
        Matrix mm = null; // 上一个矩阵
        boolean isFirst = true; // 判断是否是第一个矩阵
        for (int i = 0; i < expr.length(); i++) {
            if (isFirst && i > 0) {
                isFirst = false;
            }
            Matrix cu = null; // 当前矩阵
            char ch = expr.charAt(i);
            if (ch == '(') {
                int count = 1;
                int j = i + 1;
                while (count > 0) {
                    if (expr.charAt(j) == '(') {
                        count++;
                    } else if (expr.charAt(j) == ')') {
                        count--;
                    }
                    j++;
                }
                cu = dfs(ms, expr.substring(i + 1, j - 1));
                i = j - 1;
            }
            // 当前字符表示矩阵
            if (cu == null) {
                cu = ms[ch - 'A'];
            }
            // 首个矩阵不参与计算
            if (isFirst) {
                mm = cu;
                continue;
            }
            // 计算乘法次数,得到新的矩阵
            num += mm.getRows() * mm.getCols() * cu.getCols();
            mm = new Matrix(mm.getRows(), cu.getCols());
        }
        return mm;
    }
}

class Matrix {
    private int rows; // 矩阵行数
    private int cols; // 矩阵列数

    public Matrix(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
    }

    int getRows() {
        return this.rows;
    }

    int getCols() {
        return this.cols;
    }
}

发表于 2023-05-11 15:36:02 回复(0)

知识点: 栈 和 矩阵乘法的理解(值得一看)

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            int length = input.nextInt();
            int i = 0;
            HashMap<Character, Node> map = new HashMap<>(length);
            while (i < length) {
                Node node = new Node(input.nextInt(), input.nextInt());
                char key = (char) (65 + i);
                map.put(key, node);
                i++;
            }
            String rule = input.next();
            System.out.println(caculateTimes(map, rule));
        }
    }

    private static int caculateTimes(Map<Character, Node> data, String rules) {
        int result = 0;
        Stack<Node> stack = new Stack<>();
        while (true) {
            int startPos = rules.lastIndexOf("(");
            int endPos = rules.indexOf(")", startPos);
            if (endPos - startPos < 3) {
                break;
            }
            Node currentNode = '_' == rules.charAt(startPos + 1) ?  stack.pop() : data.get(rules.charAt(startPos + 1));
            Node nextNode = '_' == rules.charAt(startPos + 2) ? stack.pop() : data.get(rules.charAt(startPos + 2)); ;
            result += currentNode.getRow() * currentNode.getColumn() * nextNode.getColumn();
            stack.add(new Node(currentNode.getRow(), nextNode.getColumn()));
            rules = rules.replace(rules.substring(startPos, endPos + 1),  "_");
        }
        return result;
    }

    static class Node {
        private Integer row;

        private Integer column;

        public Node(Integer row, Integer column) {
            this.row = row;
            this.column = column;
        }

        public Integer getRow() {
            return row;
        }
        public Integer getColumn() {
            return column;
        }
    }
}
​
发表于 2023-05-11 08:43:18 回复(0)
public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int num = in.nextInt();
            int [][] arr = new int[num][2];                  
            for(int i = 0;i<num;i++) {
                arr[i][0] = in.nextInt();
                arr[i][1] = in.nextInt();
                in.nextLine();
            }                    
           
            String regx = in.nextLine();
            Stack<Integer> stack = new Stack<>();
           int[] sum = new int[1];
           sum[0] = 0;
           getColval(sum,regx,arr);
            System.out.println(sum[0]);
        }
    }

    public static void getColval(int[] sum,String regx,int [][] arr){
        Stack<Integer> stack = new Stack<>();    
        char[] chars = regx.toCharArray();
        boolean isQuot = false;
        for(int i=0;i<chars.length;i++){ //(A(BC))
            char cc = chars[i];
            if(cc==')'){
                int after = stack.pop();//C 2
                int before = stack.pop();//B 1
                int[] beforeArr = arr[before]; //10 20
                int[] afterArr = arr[after]; //20 5
                int num = sum[0];
                sum[0] = num + beforeArr[0]*afterArr[1]*beforeArr[1];//10 5 20
                beforeArr = new int[]{beforeArr[0],afterArr[1]};//10 5
                arr[before] = beforeArr;//给数组 重新赋值
                if(!stack.isEmpty()){
                    stack.push(before);//如果栈不为空,将B重新放入栈中
                }else{
                    break;
                }              
            }
            if(cc>=65 && cc<=90){
                stack.push(cc-'A');//0,1,2    
            }
        }
    }
发表于 2023-04-25 00:17:52 回复(0)
import java.util.*;

// (AB)C=50*10*20+50*20*5 A(BC)=10*20*5+10*5*50
public class Main {
    private static int data[][], sum = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String subExpression;
        int num = in.nextInt();
        data = new int[num][2];
        for (int i = 0; i < num; i++) {
            data[i][0] = in.nextInt();
            data[i][1] = in.nextInt();
        }

        String expression = in.next();
        String resultSubExpression = "";
        while (!resultSubExpression.equals(expression)) {
            int firstBracketsIndex = expression.indexOf(")");
             int lastBracketsIndex =-1;
            //  char c='';
            for (int i = firstBracketsIndex; i >=0; i--) {
             
                if(expression.charAt(i)=='('){
                    lastBracketsIndex = i;
                    break;
                }
            }
            subExpression = expression.substring(lastBracketsIndex, firstBracketsIndex + 1);
            resultSubExpression = calculationAmount(subExpression);
            expression = expression.replace(subExpression, resultSubExpression);


        }
        System.out.println(sum);
        // }
    }

    private static String calculationAmount(String subExpression) {
        subExpression = subExpression.replace("(", "").replace(")", "");
        int len = subExpression.length();
        int [][] subData = new int[len][2];
        String resultSubExpression = null;
        char c;
        int index;
        for (int i = 0; i < len; i++) {
            c = subExpression.charAt(i);
            index = c - 'A';
            subData[i][0] = data[index][0];
            subData[i][1] = data[index][1];
            resultSubExpression = c + "";
        }


        for (int i = 1; i < len; i++) {
            c = subExpression.charAt(i);
            index = c - 'A';
            sum += (subData[i - 1][0] * subData[i - 1][1] * subData[i][1]);
            data[index][0] = subData[i - 1][0];

        }

        return resultSubExpression;
    }
}

发表于 2023-03-13 12:53:51 回复(0)
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.Stack;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        int[][] matrixSize = new int[n][2];
        for (int i = 0; i < n; i++) {
            matrixSize[i][0] = sc.nextInt();
            matrixSize[i][1] = sc.nextInt();
            sc.nextLine();
        }
        String str = sc.nextLine();
        //map的 key为给定的矩阵名称 value为给定矩阵的行和列
        HashMap<String, int[]> map = new HashMap<>();
        int index = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= 65 && str.charAt(i) <= 90) {
                map.put(String.valueOf(str.charAt(i)), new int[]{matrixSize[index][0],matrixSize[index][1]});
                index++;
            }
        }
        Stack<String> stack = new Stack<>();
        int multiplicationCnt = 0;
        for (char s : str.toCharArray()) {
            if (s == '(' || (s >= 'A' && s <= 'Z')) {
                stack.push(String.valueOf(s));
            } else if (s == ')') {
                StringBuilder sb = new StringBuilder();
                while (!"(".equals(stack.peek())) {
                    //先弹出来的是后入的
                    String matrix2 = stack.pop();
                    String matrix1 = stack.pop();
                    sb.append(matrix1).append(matrix2);
                    int[] size1 = map.get(matrix1);
                    int[] size2 = map.get(matrix2);
                    int[] sizeNew = new int[]{size1[0],size2[1]};
                    //将这两个矩阵相乘后构成的新矩阵存入map中
                    map.put(sb.toString(), sizeNew);
                    //计算这两个矩阵的乘法量
                    multiplicationCnt += size1[0]*size2[1]*size1[1];
                }
                stack.pop();//消除上述')'对应的'('
                //将相乘后新的矩阵压入栈中
                stack.push(sb.toString());
            }
        }
        System.out.println(multiplicationCnt);
    }
}

发表于 2022-12-20 00:50:41 回复(0)
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int []row=new int[n];
            int []col=new int[n];
            for(int i=0;i<n;i++){
                row[i]=in.nextInt();
                col[i]=in.nextInt();
            }
            String s=in.next();
            Stack<Integerst=new Stack<>();
            int sum=0;
           for(int i=0,j=0;i<s.length();i++){

               if(s.charAt(i)>='A'&&s.charAt(i)<='Z'){
                   st.push(col[j]);
                   st.push(row[j]);
                   
                   j++;
                   
               }
               else if(s.charAt(i)=='('){
                   st.push(-1);
               }
               else{
                   int b=st.pop();
                   while(b!=-1){
                      st.push(b);
                      int x1=st.pop();
                      int y1=st.pop();
                      int x2=st.pop();
                      int y2=st.pop();
                      sum+=x1*y1*x2;
                      
                      b=st.pop();
                      if(b!=-1){
                      st.push(b);
                      }
                      st.push(y1);
                      st.push(x2);

                   }
               }
           }
           System.out.println(sum);
        }
    }
}
发表于 2022-12-09 22:11:00 回复(0)
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    while (sc.hasNext()) {
        int n = sc.nextInt();
        int[][] arr = new int[n][2];
        for (int i=0; i<n; i++) {
            arr[i][0] = sc.nextInt();
            arr[i][1] = sc.nextInt();
        }
        System.out.println(cul(arr, sc.next()));
    }
}

// 计算矩阵计算数
public static int cul(int[][] arr, String express) {
    Stack<Character> stack = new Stack<>();
    Stack<int[]> matrixStack = new Stack<>();
    int[] temp;
    int times = 0;
    // 入栈(分字符栈,数组栈)
    for (char c : express.toCharArray()) {
        // 遇到')',出栈计算,计算完重新入栈
        if (c == ')') {
            stack.pop();
            temp = matrixStack.pop();
            while (stack.pop() != '(') {
                times += matrixStack.peek()[0] * temp[0] * temp[1];
                temp = new int[]{matrixStack.pop()[0], temp[1]};
            }
            stack.push('t');
            matrixStack.push(temp);
            continue;
        }
        // 符号入栈,若符号不为'(',则数组也入栈
        stack.push(c);
        if (c != '(') {
            matrixStack.push(arr[c - 'A']);
        }
    }
    return times;
}

发表于 2022-09-22 00:24:48 回复(0)
利用两个栈,实现去括号的同时,确保运算顺序一致。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        Matrix[] arr = new Matrix[n];
        for(int i=0; i<n; i++){
            String[] line = br.readLine().split(" ");
            arr[i] = new Matrix(Integer.parseInt(line[0]), Integer.parseInt(line[1]));
        }
        char[] rule = br.readLine().toCharArray();
        Stack<Matrix> stack1 = new Stack<Matrix>();
        Stack<Matrix> stack2 = new Stack<Matrix>();
        int ans = 0, index=0;
        for(int i=0; i<rule.length; i++){
            if(rule[i]=='('){
                stack1.push(new Matrix(true));
            } else if(Character.isUpperCase(rule[i])){
                stack1.push(arr[index]);
                index++;
            } else if(rule[i]==')'){
                while(!stack1.peek().isBracket){
                    stack2.push(stack1.pop());
                }
                stack1.pop();
                Matrix mt1 = stack2.pop();
                while(stack2.size()>0){
                    Matrix mt2 = stack2.pop();
                    ans += mt1.row * mt1.col * mt2.col;
                    mt1.col = mt2.col;
                }
                stack1.push(mt1);
            }
        }
        if(stack1.size()>1){
            while(!stack1.isEmpty())
                stack2.push(stack1.pop());
            Matrix mt1 = stack2.pop();
            while(stack2.size()>0){
                Matrix mt2 = stack2.pop();
                ans += mt1.row * mt1.col * mt2.col;
                mt1.col = mt2.col;
            }
            stack1.push(mt1);
        }
        System.out.println(ans);
    }
}
class Matrix{
    int row;
    int col;
    boolean isBracket;
    public Matrix(){}
    public Matrix(boolean isBracket){
        this.isBracket = true;
    }
    public Matrix(int row, int col){
        this.row = row;
        this.col = col;
        this.isBracket = false;
    }
}


发表于 2022-09-02 17:00:24 回复(0)

时间超过100% 内存超过98.88%
来来回回改了好久 菜鸡也要坚持!
1、一个栈记录字符 一个栈记录矩阵规格
2、去括号 并更新
3、最后遍历统计结果

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[][] str = new String[n][2];
        String s;
        for(int i=0;i<n;i++){
            s = br.readLine();
            str[i] = s.split(" ");
        }
        int res = 0; // 统计乘法次数
        String pat = br.readLine(); // 结合方式

        // 利用栈记录结合顺序转为矩阵规格并输出
        Stack stack = new Stack(); // 记录所有字符
        Stack sst = new Stack();  // 只记录数组规格
        // 遍历结合方式 去除括号
        for(char ch : pat.toCharArray()){
            if(ch != ')'){
                stack.push(ch);
                if(ch!='('){
                    sst.push(new int[]{Integer.parseInt(str[ch-'A'][0]),Integer.parseInt(str[ch-'A'][1])}); 
                }
            } else {
                Stack st = new Stack();  // 临时存放计算括号内的矩阵
                while(stack.pop()!='('){
                    st.push(sst.pop());
                }
                if(st.size()<=1){
                    if(st.size()==1){
                        sst.push(st.pop());
                    }
                    continue;       // 若括号内的元素为1或0 表示括号无效 删除左括号并继续运算即可
                }
                // 放入计算后的新矩阵大小并将左括号弹出
                int[] tmp = st.pop(); // 弹出第一个规格元素并不断更新
                while(!st.isEmpty()){
                    int[] arr = st.pop();
                    int count = tmp[0]*arr[1]; // 相乘后的结果元素数
                    res += count * tmp[1];
                    tmp[1] = arr[1];
                }
                stack.push(' '); // 保持stack指针与sst一致 故随意加了个空格
                sst.push(tmp); // 最后把tmp输入回栈内
            }
        }
        // 遍历栈 统计结果 注意出栈为倒序 先颠倒回来
        Stack stRes = new Stack();
        while(!sst.isEmpty()){
            stRes.push(sst.pop());
        }
        int[] tmp = stRes.pop();
        while(!stRes.isEmpty()){
            int[] arr = stRes.pop();
            int count = tmp[0]*arr[1]; // 相乘后的结果元素数
            res += count * tmp[1];
            tmp[1] = arr[1];
        }
        System.out.println(res);
    }
}
发表于 2022-07-16 16:35:35 回复(0)