- 遇到'('压栈,如果栈顶是'('或者为空栈,矩阵字母直接进栈
- 遇到')',弹出两个矩阵进行计算,次顶元素 * 栈顶元素
- 计算量估计 :矩阵: A * B 矩阵 B * C,计算的结果为:A * B * C,最后将运算的结果相加起来即可
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class Main {
static class Node{
// 分别用来保存输入的行列,以及对应的矩阵
int row;
int col;
char c;// 如果是计算过的节点,统一替换为 ‘#’
}
public static void main(String[] args) {
// A x B * B * A 的矩阵相乘的计算量是 : A * B * A
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int num = sc.nextInt();
String s = sc.nextLine();// 接收输入了int型数据之后的换行
Node[] node = new Node[num];
for(int i = 0 ; i < num;i++)
node[i] = new Node();
for(int i = 0; i < num;i++){
node[i].row = sc.nextInt();
node[i].col = sc.nextInt();
node[i].c = (char)('A' + i);
}
String s2 = sc.nextLine();
// 输入表达式
StringBuffer bf = new StringBuffer(sc.nextLine());
Stack<Character> stack = new Stack<>();
Queue<Character> queue = new ArrayDeque<>();// 临时存放逆波兰算式的队列
int res = 0;
for(int i = 0;i < bf.length();i++){
char c = bf.charAt(i);
// 遍历表达式,做压栈处理
if(stack.empty() || stack.peek() == '(' || c == '(')// 如果栈顶是空,或者栈定元素是'(';直接入栈
{
stack.push(c);
}else if(Character.isLetter(c)){
stack.push(c);
}else if(c == ')'){
while(true) {
if (stack.peek() == '(') {
// 如果栈顶的元素是(,那么就直接将(出局
stack.pop();
break;
} else {
// 将两个操作数入队
char operNum1 = stack.pop();
char operNum2 = stack.pop();// operNum2 * operNum1
// 计算结果,然后将结果压栈
int row = 0;
int col1 = 0;
int col2 = 0;
int index = 0;
for(int k = 0;k < num;k++){
if(node[k].c == operNum2){
// 保存行
row = node[k].row;
col1 = node[k].col;
node[k].c = '#';
}
if(node[k].c == operNum1){
// 保存列
col2 = node[k].col;
index = k;
node[k].c = '#';
}
}
// 将第k和节点设置为结果节点,改变行
node[index].row = row;node[index].col = col2;node[index].c = operNum1;
// 结果为
res += row * col1 * col2;
// 将结果压入栈,矩阵为operNum1
if(stack.peek() != '(')// 因为前面没有将'('弹出去,如果直接将计算的结果压栈,到时候计算不准确
stack.push(operNum1);
else{
stack.pop();// 先将'(' 出栈在压栈
stack.push(operNum1);
break;
}
}
}
}
}
System.out.println(res);
}
}
}