題目要求如下:
設計程序實現矩陣的四則運算
設計要求:
(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 }
程序的亮點是矩陣的元素可以是字母,計算的時候能合並同類項,缺點是由於存儲結構的限制不能計算有負數元素的矩陣,這個在后面如果有時間我會改,補發一個。
運行結果為: