UVa442:矩阵链乘【Java】

博客详细介绍了如何解决UVa442矩阵链乘问题,包括输入矩阵维度和乘法表达式,重点在于解析表达式并计算乘法次数。使用栈数据结构解析大写字母表示的矩阵及其乘法规则,遇到右括号时计算乘法次数,简化问题处理。
摘要由CSDN通过智能技术生成

题目:

      输入n个矩阵的维度和一些矩阵的链乘表达式,输出乘法的次数。如果乘法无法进行,输出error。假定A是m*n矩阵,B是n*p的矩阵,那么A*B是m*p的矩阵,乘法次数为m*n*p。如果A的列数不等于B的行数,则乘法无法进行。

      例如,A是50*10的,B是10*20的,C是20*5的,则(A(BC))的乘法次数为10*20*5(BC的乘法次数)+50*10*5=3500。

输入:

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

输出:

3500

分析:

      本题的关键是解析表达式。表达式比较简单,可以用一个栈来完成:遇到大写字母"A~Z"时进行入栈操作,遇到右括号“)”时出栈并计算,然后将结果入栈。括号可看做入栈、出栈的标志符,无需将括号入栈,由此可将问题得到进一步简化。

package uva;
import java.util.*;
/**
 * @author Perfwxc
 *	创建矩阵Matrix类 
 *	a代表矩阵的行数
 *	b代表矩阵的列数
 */
class Matrix{
	int a,b;
	Matrix(int a,int b){
		this.a = a;
		this.b = b;
	}
}
public class Uva442 {
	public static void main(String[] args){
		//创建Matrix类型的栈并初始化,这里与C语言有所不同,不进行初始化操作对s赋值会导致空指针错误
		Stack<Matrix> s = new Stack<Matrix>();	
		//创建Matrix类型数组,题目限定(1 <= n <= 26)
		Matrix m[] = new Matrix[26];
		int n;
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		for(int i =0; i < n; i ++){
			//Java无法直接输入char类型数据,故先输入String类型数据再使用charAt()方法得到char类型数据
			String sname;
			sname = sc.next();
			char name;
			name = sname.charAt(0);
			//name - 'A'操作相当于为输入的矩阵添加索引
			int k = name - 'A';
			m[k] = new Matrix(0,0);
			//确定矩阵的行数a
			m[k].a = sc.nextInt();
			//确定矩阵的列数b
			m[k].b = sc.nextInt();		
		}
		//expr为待处理的矩阵运算表达式
		String expr;
		while(sc.hasNext()){
			expr = sc.next();
			int len = expr.length();
			boolean error =false;
			//ans表示需要进行乘法运算的总次数
			int ans = 0;
			for(int i =0; i < len; i ++){
				//使用Character.isLetter()函数判断字符串的第i个字符是否为字母,若是字母,为其加入索引后进行入栈操作
				if(Character.isLetter(expr.charAt(i))) s.push(m[expr.charAt(i)-'A']);
				//当遇到")"时进行出栈并运算
				else if(expr.charAt(i) == ')'){
					//取栈顶元素后出栈
					Matrix m2 = s.peek(); s.pop();
					Matrix m1 = s.peek(); s.pop();
					//判断矩阵m1的列数与矩阵m2的行数是否相等,若不相等,则无法进行矩阵运算
					if(m1.b != m2.a){
						error = true;
						break;
					}
					//两矩阵[m,n],[n,p]相乘,所需乘法操作数为m*n*p
					ans += m1.a * m1.b * m2.b;
					//运算完毕后,将运算结果入栈
					s.push(new Matrix(m1.a,m2.b));
				}
			}
			if(error)
				System.out.println("error");
			else 
				System.out.println(ans);
		}
	}


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值