題目描述
矩陣乘法的運算量與矩陣乘法的順序強相關。
例如:
A是一個50×10的矩陣,B是10×20的矩陣,C是20×5的矩陣
計算A*B*C有兩種順序:((AB)C)或者(A(BC)),前者須要計算15000次乘法,後者只須要3500次。
編寫程序計算不一樣的計算順序須要進行的乘法次數
輸入描述
輸入多行,先輸入要計算乘法的矩陣個數n,每一個矩陣的行數,列數,總共2n的數,最後輸入要計算的法則
輸出描述
輸出須要進行的乘法次數
輸入例子
3
50 10
10 20
20 5
(A(BC))
輸出例子
3500
算法實現
import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;
/**
* Declaration: All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
while (scanner.hasNext()) {
int num = scanner.nextInt();
int[] arr = new int[num * 2];
for (int i = 0; i < arr.length; i++) {
arr[i] = scanner.nextInt();
}
String rule = scanner.next();
System.out.println(estimate(arr, rule));
}
scanner.close();
}
/**
* 按照法計算乘法的計算量
*
* @param arr 矩陣的大小
* @param rule 計算法則
* @return 執行乘法的次數
*/
private static int estimate(int[] arr, String rule) {
Deque<Integer> stack = new LinkedList<>();
// Deque<Character> chars = new LinkedList<>();
//
// StringBuilder builder = new StringBuilder(rule.length());
int idxArr = 0;
int idx = 0;
int result = 0;
while (idx < rule.length()) {
char c = rule.charAt(idx);
// c不是括號
if (c != '(' && c != ')') {
// 若是是第一個字符
if (idx == 0) {
stack.addLast(arr[idxArr]);
stack.addLast(arr[idxArr + 1]);
}
// 不是第一個字符
else {
// 取前一個字符
char prev = rule.charAt(idx - 1);
// 若是不是括號就要進行計算
if (prev != '(' && prev != ')') {
// 第一個矩陣的行數和列數
int col = stack.removeLast();
int row = stack.removeLast();
int col2 = arr[idxArr + 1];
result += row * col * col2;
stack.add(row);
stack.add(col2);
}
// 若是是括號就要添加到棧中
else {
stack.addLast(arr[idxArr]);
stack.addLast(arr[idxArr + 1]);
}
// 移動到下一個矩陣
idxArr += 2;
}
}
// 處理下一個字符
idx++;
}
// 最後stack中只會剩下一個矩陣,只有行和列
// 要從後向前計算
while (stack.size() > 2) {
int col2 = stack.removeLast();
int row2 = stack.removeLast();
int col1 = stack.removeLast();
int row1 = stack.removeLast();
stack.addLast(row1);
stack.addLast(col2);
result += row1 * col1 * col2;
}
return result;
}
}