UVa442 Matrix Chain Multiplication(矩阵链乘)java实现

题目描述:输入n个矩阵的维度和一个矩阵链乘的表达式,输出乘法的次数,如果乘法无法进行,则输出error。


根据题意,矩阵我定义为一个有rol,row两个属性的对象,我们手动输入一系列的矩阵

然后输入矩阵链乘表达式,其中表达式内可能有括号,所以括号内的要想相乘,否则应该从左向右乘(矩阵相乘是不符合交换律的)


使用栈来解决,第一个站用于存储矩阵,一个栈用于存储左括号的位置

顺序扫描矩阵链乘表达式,遇到矩阵(也就是非括号,程序里面我直接用矩阵在数组中的下标表示),将其装入矩阵栈。遇到左括号,将遇到左括号的位置,装入括号栈。遇到右括号,我们从括号栈里面记录的最后一个左括号的位置开始,将矩阵连乘,一直到右括号为止。

乘的过程中,如果出现不能相乘,结束程序;如果连乘结束,将结果矩阵装入矩阵栈(注意将矩阵栈中,刚才连乘的矩阵全部清空)

上述过程后,矩阵栈中,是一系列可以直接顺序链乘的矩阵,连乘之,同样,如果出现不能相乘,结束程序;否则等到最后的矩阵结果


public class Matrix {
	int col = 0;
	int row = 0;
	public Matrix(int col,int row) {
		this.col = col;//列
		this.row = row;//行
	}		
}


public class Test {    
    //矩阵相乘,返回新矩阵
    public static Matrix multiply(Matrix a , Matrix b )  {  
        return new Matrix( a.col,b.row);         
    }  
    
    public static boolean can_mul(Matrix a , Matrix b )  {  
        if( a.row == b.col ) return true ;  
        return false ;  
    }  
    
    public static void main(String[] args) {
        int total = 4;//矩阵数目
        Matrix[] matrixs = new Matrix[total];
        matrixs[0] = new Matrix(3,3);
        matrixs[1] = new Matrix(3,4);
        matrixs[2] = new Matrix(4,5);
        matrixs[3] = new Matrix(5,6);
        
        String[] str= {"0","(","1","2",")","3"};//乘法表达式
        Matrix[] stack = new Matrix[str.length];//矩阵栈
        int[] left = new int[str.length];//括号栈,用于存放左括号的位置
        
        int stackLen = 0;//用于记录矩阵栈的末端
        int mL = 0;//mL+1=矩阵进入栈的数目
        //一个m×n的矩阵a(m,n)左乘一个n×p的矩阵b(n,p),会得到一个m×p的矩阵c(m,p)
        for(int i=0,j=0,k=0;i<str.length;i++){
            if(str[i] == "("){//如果是左括号,进入括号栈
                left[j] = stackLen;//记录栈中左括号应在矩阵栈的位置                
                j++;
            }else if(str[i] == ")"){//如果是右括号                            
                Matrix tmp = stack[left[j-1]];//遇到右括号前,最后一次记录左括号右边的第一个矩阵
                for(int m=left[j-1]+1;m<stackLen;m++){//将左右括号内的矩阵相乘
                    if(can_mul(tmp, stack[m])){//如果能相乘
                        tmp = multiply(tmp, stack[m]);
                    }else{//如果不能相乘,结束程序
                        System.out.println("error");
                        System.exit(-1);
                    }
                }
                stack[left[j-1]] = tmp;//将新矩阵放入栈
                
                stackLen = left[j-1]+1;//将矩阵栈从新矩阵开始继续计数                
                for(int n=stackLen;n<stack.length;n++){//将后面的矩阵清空
                    stack[n] = null;
                }
                j--;//将括号栈内,最后一个左括号去掉
                
            }else{//如果是矩阵,进入矩阵栈
                stack[stackLen] = matrixs[mL];
                System.out.println(stack[stackLen].row);
                stackLen++;            
                mL++;
            }
        }

        Matrix tmp = stack[0];        
        for(int i = 1;i<stackLen;i++){//顺序计算矩阵相乘
            if(can_mul(tmp, stack[i])){
                tmp = multiply(tmp, stack[i]);
            }else{
                System.out.println("error");
                System.exit(-1);
            }
        }
        
        System.out.println("结果为row="+tmp.row+",col="+tmp.col+"的矩阵");
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值