题目要求如下:
设计程序实现矩阵的四则运算
设计要求:
(1) 实现矩阵的四则运算。
(2) 考虑实现带变元的矩阵计算。
(3)考虑实现矩阵的特征值和特征向量的计算。
我使用java语言写的
目录结构如下所示:
Matrix类是对矩阵的建模,我用一个String类型的二维数组存放矩阵的元素,除此之外还有矩阵的行数和列数两个属性。代码如下:
1 package org.java.pojo; 2 3 public class Matrix { 4 private String matrix[][]; 5 private int row; 6 private int line; 7 public String[][] getMatrix() { 8 return matrix; 9 } 10 public void setMatrix(String[][] matrix) { 11 this.matrix = matrix; 12 } 13 public int getRow() { 14 return row; 15 } 16 public void setRow(int row) { 17 this.row = row; 18 } 19 public int getLine() { 20 return line; 21 } 22 public void setLine(int line) { 23 this.line = line; 24 } 25 }
所有的调用逻辑写在在Begin.java里面,这里根据用户的选择,调用相应的方法。
具体的代码为:
1 package org.java.main; 2 3 import java.util.Scanner; 4 5 import org.java.dao.Caculate; 6 import org.java.pojo.Matrix; 7 public class Begin { 8 public static Scanner scan = new Scanner(System.in); 9 public static void main(String[] args){ 10 int chooseChar=0; 11 while(chooseChar!=5){ 12 System.out.println("请选择要执行的运算"); 13 System.out.println("1、加法\n2、减法\n3、乘法\n4、求矩阵的特征值和特征向量\n5、退出"); 14 try { 15 chooseChar=scan.nextInt(); 16 scan.nextLine();//用于处理输入结束之后的回车,否则会影响后面的输入 17 } catch (Exception e) { 18 e.printStackTrace(); 19 } 20 Begin beg=new Begin(); 21 switch(chooseChar){ 22 case 1:{ 23 beg.addOperation(); 24 break; 25 } 26 case 2:{ 27 beg.reduceOperation(); 28 break; 29 } 30 case 3:{ 31 beg.multiplyOperation(); 32 break; 33 } 34 case 4:{ 35 beg.complexOperation(); 36 break; 37 } 38 } 39 if(chooseChar==5){ 40 System.out.println("已停止工作"); 41 } 42 } 43 } 44 public static void publicPrint() { 45 System.out.println("请输入矩阵,元素之间用逗号隔开,可以有变元,输入“quit”结束,如:\n" 46 + "1,2,3\n" 47 + "2,3,4\n" 48 + "3,4,5\n" 49 + "quit"); 50 } 51 52 /** 53 * 65~90:A~Z 54 * 97~122:a~z 55 * 选择加 56 * @param list 57 */ 58 public void addOperation(){ 59 System.out.println("您选择的是矩阵的加法运算,注意两个矩阵行数和列数要相等"); 60 Caculate caculate=new Caculate(); 61 publicPrint(); 62 Matrix matrix1=caculate.inputMatrix(); 63 System.out.println("请输入下一个矩阵:"); 64 Matrix matrix2=caculate.inputMatrix(); 65 Matrix matrix=null; 66 try { 67 matrix=caculate.addOperation(matrix1, matrix2);//调用封装方法计算 68 } catch (Exception e) { 69 e.printStackTrace(); 70 } 71 System.out.println("运算结果为:"); 72 caculate.printMatrix(matrix); 73 } 74 75 /** 76 * 65~90:A~Z 77 * 97~122:a~z 78 * 选择减 79 * @param list 80 */ 81 public void reduceOperation(){ 82 System.out.println("您选择的是矩阵的减法运算,注意两个矩阵行数和列数要相等"); 83 Caculate caculate=new Caculate(); 84 publicPrint(); 85 Matrix matrix1=caculate.inputMatrix(); 86 System.out.println("请输入下一个矩阵:"); 87 Matrix matrix2=caculate.inputMatrix(); 88 Matrix matrix=null; 89 try { 90 matrix=caculate.reduceOperation(matrix1, matrix2);//调用封装方法计算 91 } catch (Exception e) { 92 e.printStackTrace(); 93 } 94 System.out.println("运算结果为:"); 95 caculate.printMatrix(matrix); 96 } 97 98 /** 99 * 65~90:A~Z 100 * 97~122:a~z 101 * 选择乘 102 * @param list 103 */ 104 public void multiplyOperation(){ 105 System.out.println("您选择的是矩阵的乘法运算,注意第一个矩阵的列数要和第二个矩阵的行数相等"); 106 Caculate caculate=new Caculate(); 107 publicPrint(); 108 Matrix matrix1=caculate.inputMatrix(); 109 System.out.println("请输入下一个矩阵:"); 110 Matrix matrix2=caculate.inputMatrix(); 111 Matrix matrix=null; 112 try { 113 matrix=caculate.multiplyOperation(matrix1, matrix2);//调用封装方法计算 114 } catch (Exception e) { 115 e.printStackTrace(); 116 } 117 System.out.println("运算结果为:"); 118 caculate.printMatrix(matrix); 119 } 120 /** 121 * 65~90:A~Z 122 * 97~122:a~z 123 * 选择特征值特征向量 124 * @param list 125 */ 126 public void complexOperation(){ 127 System.out.println("您选择的是计算矩阵的特征值特征向量"); 128 Caculate caculate=new Caculate(); 129 publicPrint(); 130 Matrix matrix=caculate.inputMatrix(); 131 System.out.println("运算结果为:"); 132 MatrixEigenValue.caculateEigen(matrix.getMatrix()); 133 } 134 135 136 }
所有的计算封装在在Caculate.java里面,这里包含了矩阵的输入生成和矩阵的运算。里面的方法为:
具体的代码为:
1 package org.java.dao; 2 3 import java.util.ArrayList; 4 import java.util.Scanner; 5 6 import org.java.pojo.Matrix; 7 8 public class Caculate { 9 /** 10 * 从输入到创建一个矩阵 11 * @return 12 */ 13 public Matrix inputMatrix(){ 14 @SuppressWarnings("resource") 15 Scanner scan = new Scanner(System.in); 16 ArrayList<String> list=new ArrayList<String>();//用来存放用户的输入 17 String firstString=scan.nextLine(); 18 while(!firstString.equals("quit")){ 19 if(!"".equals(firstString)) 20 list.add(firstString); 21 firstString=scan.nextLine(); 22 } 23 int row=list.size();//获得矩阵的行数 24 int line=list.get(0).split(",").length;//获得矩阵列数 25 for(int i=1;i<row;++i){ 26 if(line!=(list.get(i).split(",").length)){ 27 System.out.println("每行的元素个数不相等"); 28 System.exit(0); 29 return null; 30 } 31 } 32 Matrix matrix=new Matrix(); 33 matrix.setRow(row); 34 matrix.setLine(line); 35 String matrixString[][]=new String[row][line]; 36 int i=0,j=0; 37 for (String string : list) {//分出每一行 38 String tempString[]=string.split(","); 39 for (String str : tempString) { 40 matrixString[i][j]=str.trim();//删除空格 41 ++j; 42 } 43 if(j==line) 44 j=0; 45 ++i; 46 } 47 matrix.setMatrix(matrixString); 48 return matrix; 49 } 50 51 /** 52 * 输出矩阵 53 * @param matrix 54 */ 55 public void printMatrix(Matrix matrix){ 56 String matrixString[][]=matrix.getMatrix(); 57 for(int i=0;i<matrix.getRow();++i){ 58 for(int j=0;j<matrix.getLine();++j){ 59 System.out.print(matrixString[i][j]+"\t"); 60 } 61 System.out.println(); 62 } 63 } 64 65 /** 66 * 矩阵加法 67 * @param matrix1 68 * @param matrix2 69 * @return 70 * @throws Exception 71 */ 72 @SuppressWarnings("null") 73 public Matrix addOperation(Matrix matrix1,Matrix matrix2) throws Exception{ 74 //如果输入有误,则停止运算 75 if(matrix1==null){ 76 throw new Exception(); 77 } 78 //如果输入有误,则停止运算 79 if(matrix2==null){ 80 throw new Exception(); 81 } 82 //计算---首先判断一下两个矩阵行和列的关系是否可以计算 83 if(matrix1.getRow()!=matrix2.getRow()||matrix1.getLine()!=matrix2.getLine()){ 84 System.out.println("两个矩阵行不满足运算要求"); 85 throw new Exception(); 86 } 87 Matrix matrix=new Matrix(); 88 matrix.setRow(matrix1.getRow()); 89 matrix.setLine(matrix1.getLine()); 90 //执行运算 91 String[][]matString1=matrix1.getMatrix(); 92 String[][]matString2=matrix2.getMatrix(); 93 String[][]matString=new String[matrix.getRow()][matrix.getLine()];//结果矩阵的数组 94 for(int i=0;i<matrix.getRow();++i){ 95 for(int j=0;j<matrix.getLine();++j){ 96 if(!isNumber(matString1[i][j])||!isNumber(matString2[i][j])){ 97 matString[i][j]=matString1[i][j]+"+"+matString2[i][j]; 98 }else{ 99 //将结果再转换成string 100 //转换成float的值相加减 101 float result=Float.parseFloat(matString1[i][j])+Float.parseFloat(matString2[i][j]); 102 matString[i][j]=String.valueOf(result); 103 } 104 } 105 106 } 107 matrix.setMatrix(matString); 108 return matrix; 109 } 110 /** 111 * 112 * 减 113 * @param matrix1 114 * @param matrix2 115 * @return 116 * @throws Exception 117 */ 118 public Matrix reduceOperation(Matrix matrix1,Matrix matrix2)throws Exception{ 119 //如果输入有误,则停止运算 120 if(matrix1==null){ 121 throw new Exception(); 122 } 123 //如果输入有误,则停止运算 124 if(matrix2==null){ 125 throw new Exception(); 126 } 127 //计算---首先判断一下两个矩阵行和列的关系是否可以计算 128 if(matrix1.getRow()!=matrix2.getRow()||matrix1.getLine()!=matrix2.getLine()){ 129 System.out.println("两个矩阵行不满足运算要求"); 130 throw new Exception(); 131 } 132 Matrix matrix=new Matrix(); 133 matrix.setRow(matrix1.getRow()); 134 matrix.setLine(matrix1.getLine()); 135 //执行运算 136 String[][]matString1=matrix1.getMatrix(); 137 String[][]matString2=matrix2.getMatrix(); 138 String[][]matString=new String[matrix.getRow()][matrix.getLine()];//结果矩阵的数组 139 for(int i=0;i<matrix.getRow();++i){ 140 for(int j=0;j<matrix.getLine();++j){ 141 if(!isNumber(matString1[i][j])||!isNumber(matString2[i][j])){ 142 matString[i][j]=matString1[i][j]+"-"+matString2[i][j]; 143 }else{ 144 //将结果再转换成string 145 //转换成float的值相加减 146 float result=Float.parseFloat(matString1[i][j])-Float.parseFloat(matString2[i][j]); 147 matString[i][j]=String.valueOf(result); 148 } 149 } 150 151 } 152 matrix.setMatrix(matString); 153 return matrix; 154 } 155 156 /** 157 * 乘 158 * @param matrix1 159 * @param matrix2 160 * @return 161 * @throws Exception 162 */ 163 public Matrix multiplyOperation(Matrix matrix1,Matrix matrix2)throws Exception{ 164 //如果输入有误,则停止运算 165 if(matrix1==null){ 166 throw new Exception(); 167 } 168 //如果输入有误,则停止运算 169 if(matrix2==null){ 170 throw new Exception(); 171 } 172 //计算---首先判断一下两个矩阵行和列的关系是否可以计算 173 if(matrix1.getLine()!=matrix2.getRow()){ 174 System.out.println("两个矩阵行不满足运算要求"); 175 throw new Exception(); 176 } 177 Matrix matrix=new Matrix(); 178 matrix.setRow(matrix1.getRow());//结果矩阵行数等于第一个矩阵行数,列数等于第二个矩阵列数 179 matrix.setLine(matrix2.getLine()); 180 //执行运算 181 String[][]matString1=matrix1.getMatrix(); 182 String[][]matString2=matrix2.getMatrix(); 183 String[][]matString=new String[matrix.getRow()][matrix.getLine()];//结果矩阵的数组 184 int sameNum=matrix1.getLine();//=matrix2.getRow() 185 for(int i=0;i<matrix.getRow();++i){ 186 for(int j=0;j<matrix.getLine();++j){ 187 matString[i][j]=""; 188 for(int k=0;k<sameNum;++k){ 189 matString[i][j]+=matString1[i][k]+"*"+matString2[k][j]+"+"; 190 } 191 matString[i][j]=doAnalyze(matString[i][j]);//把计算式合并同类项并计算,重新赋给矩阵相应元素 192 } 193 } 194 matrix.setMatrix(matString); 195 return matrix; 196 } 197 198 /** 199 * 把形如“1*1+2*1+3*1+”的式子进行分析计算 200 * 返回处理结果 201 * @param toAnalizeString 202 * @return 203 */ 204 public String doAnalyze(String toAnalizeString){ 205 String disAdd[]=toAnalizeString.split("\\+");//“+”是转义字符 206 int addLength=disAdd.length;//获取有几项相加 207 String disMul[][]=new String[addLength][2];//所有项都在这一个二维数组里面了 208 for (int i = 0; i < disAdd.length; i++) { 209 disMul[i]=disAdd[i].split("\\*"); 210 } 211 //移项,先不考虑系数为0的情况 212 for(int i = 0; i < disMul.length; i++){ 213 214 if(isNumber(disMul[i][0])){ 215 if(isNumber(disMul[i][1])){ 216 //都是数字,让第一项等于两数运算结果,第二项等于0 217 float result=Float.parseFloat(disMul[i][0])*Float.parseFloat(disMul[i][1]); 218 disMul[i][0]=String.valueOf(result); 219 disMul[i][1]="0"; 220 }else{ 221 //一是二不是,不用做什么 222 } 223 }else{ 224 if(isNumber(disMul[i][1])){ 225 //一不是二是,互换 226 String tempString=disMul[i][0]; 227 disMul[i][0]=disMul[i][1]; 228 disMul[i][1]=tempString; 229 }else{ 230 //都不是数字,让第一项等于1,第二项等于两数运算结果 231 if(disMul[i][0].equals(disMul[i][1])){ 232 disMul[i][1]=disMul[i][1]+"^2"; 233 }else{//按abc顺序写 234 if(disMul[i][0].compareTo(disMul[i][1])>0){ 235 disMul[i][1]=disMul[i][1]+""+disMul[i][0]; 236 }else{ 237 disMul[i][1]=disMul[i][0]+""+disMul[i][1]; 238 } 239 } 240 disMul[i][0]="1"; 241 } 242 } 243 }//移项完成 244 245 //合并同类项,算法会处理系数为0的情况 246 for(int i = 0; i < disMul.length-1; i++){ 247 for(int j=i+1;j<disMul.length;j++){ 248 if(!disMul[i][0].equals("0")){ 249 if(disMul[i][1].equals(disMul[j][1])){//如果是同类项,系数相加,赋值给上面的系数,下面的系数置为0 250 disMul[i][0]=String.valueOf(Float.parseFloat(disMul[i][0])+Float.parseFloat(disMul[j][0])); 251 disMul[j][0]="0"; 252 } 253 } 254 } 255 }//合并同类项完成 256 257 //写成多项式的形式,用result拼接 258 String result=""; 259 for(int i = 0; i < disMul.length; i++){ 260 if(!disMul[i][0].equals("0")){//忽略为0的项 261 if(disMul[i][1].equals("0")){//如果是常数项 262 result+=disMul[i][0]+"+"; 263 }else{ 264 result+=disMul[i][0]+disMul[i][1]+"+"; 265 } 266 } 267 } 268 result=result.substring(0, result.length()-1);//删除最后一个“+”号 269 return result; 270 } 271 272 /** 273 * 判断矩阵的一个元素是字母还是数字 274 * @param str 275 * @return 276 */ 277 public boolean isNumber(String str){ 278 for (int i = 0; i < str.length(); i++){ 279 if (!Character.isDigit(str.charAt(i))){ 280 return false; 281 } 282 } 283 return true; 284 } 285 }
程序的亮点是矩阵的元素可以是字母,计算的时候能合并同类项,缺点是由于存储结构的限制不能计算有负数元素的矩阵,这个在后面如果有时间我会改,补发一个。
运行结果为: