JavaSE基础之矩阵运算

JavaSE基础之矩阵运算

1、矩阵类:Matrix.java

包括矩阵的加、乘运算,行列式的求解,最大最小元素等

  1 package cn.com.zfc.help;
  2 
  3 import java.text.DecimalFormat;
  4 import java.util.HashMap;
  5 import java.util.HashSet;
  6 import java.util.Map;
  7 import java.util.Scanner;
  8 import java.util.Set;
  9 
 10 /**
 11 * 
 12 * @title Matrix
 13 * @describe 矩阵运算
 14 * @author 张富昌
 15 * @date 2017年3月21日下午6:45:00
 16 */
 17 public class Matrix {
 18   // 使用二维数组模拟矩阵
 19   private int[][] matrix;
 20   private int row;
 21   private int cel;
 22 
 23  
 24 
 25   /**
 26   * 构造方法
 27   * 
 28   * @param row:矩阵的行数
 29   * @param cel:矩阵的列数
 30   */
 31   public Matrix(int row, int cel) {
 32     this.row = row;
 33     this.cel = cel;
 34     // 初始化数组
 35     matrix = new int[this.row][this.cel];
 36   }
 37 
 38  
 39 
 40   // 为私有属性添加 setter()和getter()方法:赋值,取值
 41   public int getRow() {
 42     return row;
 43   }
 44 
 45  
 46 
 47   public void setRow(int row) {
 48     this.row = row;
 49   }
 50 
 51  
 52 
 53   public int getCel() {
 54     return cel;
 55   }
 56 
 57  
 58 
 59   public void setCel(int cel) {
 60     this.cel = cel;
 61   }
 62 
 63  
 64 
 65   public int[][] getMatrix() {
 66     return matrix;
 67   }
 68 
 69  
 70 
 71   public void setMatrix(int[][] matrix) {
 72     this.matrix = matrix;
 73   }
 74 
 75  
 76 
 77   /**
 78   * 快速初始化矩阵中的成员变量:二维数组
 79   */
 80   public void initMatrix() {
 81     Scanner scanner = new Scanner(System.in);
 82     for (int i = 0; i < this.getRow(); i++) {
 83       for (int j = 0; j < this.getCel(); j++) {
 84         // 自己输入
 85         // matrix[i][j] = scanner.nextInt();
 86         // 生成一个 0-100 的随机数
 87         matrix[i][j] = (int) (Math.random() * 100 + 1);
 88         // 在测试矩阵中元素的种类及其个数时,不用随机赋值,即注释上一行代码
 89         // matrix[i][j] = i;
 90       }
 91     }
 92   }
 93 
 94  
 95 
 96   /**
 97   * 输出矩阵
 98   */
 99   public void printMatrix() {
100     for (int i = 0; i < this.getRow(); i++) {
101       for (int j = 0; j < this.getCel(); j++) {
102         System.out.print(matrix[i][j] + "	");
103       }
104       System.out.println();
105     }
106   }
107 
108  
109 
110   /**
111   * 
112   * @param matrix1:第一个矩阵
113   * @param matrix2:第二个矩阵
114   * @return:两个矩阵相加之后的矩阵
115   */
116   public Matrix addMatrix(Matrix matrix1, Matrix matrix2) {
117     if ((matrix1.getRow() == matrix2.getRow()) && (matrix1.getCel() == matrix2.getCel())) {
118       // 中间矩阵,相加之后的结果
119       Matrix m = new Matrix(matrix1.getRow(), matrix2.getCel());
120 
121  
122 
123       for (int i = 0; i < m.getRow(); i++) {
124         for (int j = 0; j < m.getCel(); j++) {
125           m.getMatrix()[i][j] = matrix1.getMatrix()[i][j] + matrix2.getMatrix()[i][j];
126         }
127       }
128       return m;
129     } else {
130       return null;
131     }
132 
133  
134 
135   }
136 
137  
138 
139   /**
140   * 
141   * @param matrix1:第一个矩阵
142   * @param matrix2:第二个矩阵
143   * @return:两个矩阵相乘之后的矩阵
144   */
145   public Matrix mulMatrix(Matrix matrix1, Matrix matrix2) {
146     if (matrix1.getRow() == matrix2.getCel()) {
147 
148  
149 
150       Matrix m = new Matrix(matrix1.getRow(), matrix2.getCel());
151 
152  
153 
154       for (int i = 0; i < matrix1.getRow(); i++) {
155         for (int j = 0; j < matrix2.getCel(); j++) {
156           int sum = 0;
157           for (int k = 0; k < matrix1.getCel(); k++) {
158             sum += matrix1.getMatrix()[i][k] * matrix2.getMatrix()[k][j];
159           }
160           m.getMatrix()[i][j] = sum;
161         }
162       }
163       return m;
164     } else {
165       return null;
166     }
167   }
168 
169  
170 
171   /**
172   * 矩阵转置
173   * 
174   * @param matrix
175   * @return 转置后的矩阵
176   */
177   public Matrix reverse(Matrix matrix) {
178 
179  
180 
181     Matrix m = new Matrix(matrix.getCel(), matrix.getRow());
182 
183  
184 
185     for (int i = 0; i < m.getCel(); i++) {
186 
187  
188 
189       for (int j = 0; j < m.getRow(); j++) {
190 
191  
192 
193         m.getMatrix()[j][i] = matrix.getMatrix()[i][j];
194       }
195     }
196     return m;
197   }
198 
199  
200 
201   /**
202   * 
203   * @param matrix
204   * @return:返回最大的值
205   */
206   public int getMaxNumber(Matrix matrix) {
207     // 设置假设的默认的最大值(一般不是)
208     int max = matrix.getMatrix()[0][0];
209 
210  
211 
212     for (int i = 0; i < matrix.getRow(); i++) {
213       for (int j = 0; j < matrix.getCel(); j++) {
214         if (max < matrix.getMatrix()[i][j]) {
215           max = matrix.getMatrix()[i][j];
216         }
217       }
218     }
219     return max;
220   }
221 
222  
223 
224   /**
225   * 
226   * @param matrix
227   * @return:返回最小的值
228   */
229   public int getMinNumber(Matrix matrix) {
230     int min = matrix.getMatrix()[0][0];
231     for (int i = 0; i < matrix.getRow(); i++) {
232       for (int j = 0; j < matrix.getCel(); j++) {
233         if (min > matrix.getMatrix()[i][j]) {
234           min = matrix.getMatrix()[i][j];
235         }
236       }
237     }
238     return min;
239   }
240 
241  
242 
243   /**
244   * 
245   * @param matrix
246   * @return:每一行元素的最大值组成的数组
247   */
248   public int[] getEachRowMax(Matrix matrix) {
249     int[] arr = new int[matrix.getRow()];
250     for (int i = 0; i < matrix.getRow(); i++) {
251       // 找出每一行的最大值
252       // 中间变量
253       int temp = matrix.getMatrix()[i][0];
254       for (int j = 0; j < matrix.getCel(); j++) {
255         if (temp < matrix.getMatrix()[i][j]) {
256           temp = matrix.getMatrix()[i][j];
257         }
258       }
259       arr[i] = temp;
260     }
261     return arr;
262   }
263 
264  
265 
266   /**
267   * 
268   * @param matrix
269   * @return:每一行的最小值
270   */
271   public int[] getEachRowMin(Matrix matrix) {
272     int[] arr = new int[matrix.getRow()];
273     for (int i = 0; i < matrix.getRow(); i++) {
274       // 找出每一行的最小值
275       // 中间变量
276       int temp = matrix.getMatrix()[i][0];
277       for (int j = 0; j < matrix.getCel(); j++) {
278         if (temp > matrix.getMatrix()[i][j]) {
279           temp = matrix.getMatrix()[i][j];
280         }
281       }
282       arr[i] = temp;
283      }
284     return arr;
285    }
286 
287  
288 
289   /**
290   * 
291   * @param matrix
292   * @return:每一列元素的最小值组成的数组
293   */
294   public int[] getEachCelMin(Matrix matrix) {
295     // 先转置
296     Matrix m = matrix.reverse(matrix);
297     // 后求每一行的最小值
298     int[] arr = m.getEachRowMin(m);
299     return arr;
300   }
301 
302  
303 
304   public Matrix sort(Matrix matrix) {
305     Matrix m = new Matrix(matrix.getRow(), matrix.getCel());
306     m.setMatrix(matrix.getMatrix());
307     // 中间变量,用来存放矩阵的元素
308     int[] arr = new int[m.getRow() * m.getCel()];
309     int count = 0;
310     // 将二维数组转化为一维数组
311     for (int i = 0; i < m.getRow(); i++) {
312       for (int j = 0; j < m.getCel(); j++) {
313         arr[count] = m.getMatrix()[i][j];
314         count++;
315       }
316     }
317     // 对一维数组进行排序:冒泡排序
318     arr = bubbleSort(arr);
319     for (int i = 0; i < m.getRow(); i++) {
320       for (int j = 0; j < m.getCel(); j++) {
321         count--;
322         m.getMatrix()[i][j] = arr[count];
323       }
324     }
325     return m;
326   }
327 
328  
329 
330   /**
331   * 
332   * 功能:冒泡排序的基本思想就是不断比较相邻的两个数,让较大的元素不断地往后移。经过一轮比较,就选出最大的数;经过第2轮比较,就选出次大的数,
333   * 以此类推。
334   *
335   * 
336   * 参数:int[] array
337   *
338   * 返回类型:int[]
339   */
340   public int[] bubbleSort(int[] array) {
341     // 使用临时数组,替代原始数组
342     int[] arr = array;
343     for (int i = 0; i < arr.length; i++) {
344       for (int j = 0; j < arr.length - 1 - i; j++) {
345         if (arr[j] < arr[j + 1]) {
346           int temp = arr[j];
347           arr[j] = arr[j + 1];
348           arr[j + 1] = temp;
349         }
350       }
351     }
352     return arr;
353   }
354 
355  
356 
357   public Map<Integer, Integer> getElementAndCount(Matrix matrix) {
358     // 存放的是键值对, 1-3 ,2-4
359     Map<Integer, Integer> map = new HashMap<>();
360     // 判断重复的元素
361     Set<Integer> set = new HashSet<>();
362     for (int i = 0; i < matrix.getRow(); i++) {
363       for (int j = 0; j < matrix.getCel(); j++) {
364         if (set.add(matrix.getMatrix()[i][j])) {
365           map.put(matrix.getMatrix()[i][j], 1);
366         } else {
367           map.replace(matrix.getMatrix()[i][j], map.get(matrix.getMatrix()[i][j]) + 1);
368         }
369       }
370     }
371     return map;
372   }
373 
374  
375 
376   public void showType() {
377     System.out.println("-------------------------------------");
378   }
379 
380  
381 
382   /***
383   * 求行列式的算法
384   * 
385   * @param value
386   * 需要算的行列式
387   * @return 计算的结果
388   */
389   public int mathDeterminantCalculation(int[][] value) throws Exception {
390     if (value.length == 1) {
391       // 当行列式为1阶的时候就直接返回本身
392       return value[0][0];
393     } else if (value.length == 2) {
394       // 如果行列式为二阶的时候直接进行计算
395       return value[0][0] * value[1][1] - value[0][1] * value[1][0];
396     }
397     // 当行列式的阶数大于2时
398     int result = 1;
399     for (int i = 0; i < value.length; i++) {
400       // 检查数组对角线位置的数值是否是0,如果是零则对该数组进行调换,查找到一行不为0的进行调换
401       if (value[i][i] == 0) {
402         value = changeDeterminantNoZero(value, i, i);
403         result *= -1;
404       }
405       for (int j = 0; j < i; j++) {
406         // 让开始处理的行的首位为0处理为三角形式
407         // 如果要处理的列为0则和自己调换一下位置,这样就省去了计算
408         if (value[i][j] == 0) {
409           continue;
410         }
411         // 如果要是要处理的行是0则和上面的一行进行调换
412         if (value[j][j] == 0) {
413           int[] temp = value[i];
414           value[i] = value[i - 1];
415           value[i - 1] = temp;
416           result *= -1;
417           continue;
418         }
419         int ratio = -(value[i][j] / value[j][j]);
420         value[i] = addValue(value[i], value[j], ratio);
421       }
422     }
423     DecimalFormat df = new DecimalFormat(".##");
424     return Integer.parseInt(df.format(mathValue(value, result)));
425   }
426 
427  
428 
429   /**
430   * 计算行列式的结果
431   * 
432   * @param value
433   * @return
434   */
435   public int mathValue(int[][] value, int result) throws Exception {
436     for (int i = 0; i < value.length; i++) {
437       // 如果对角线上有一个值为0则全部为0,直接返回结果
438       if (value[i][i] == 0) {
439         return 0;
440       }
441       result *= value[i][i];
442     }
443     return result;
444   }
445 
446  
447 
448   /***
449   * 将i行之前的每一行乘以一个系数,使得从i行的第i列之前的数字置换为0
450   * 
451   * @param currentRow
452   * 当前要处理的行
453   * @param frontRow
454   * i行之前的遍历的行
455   * @param ratio
456   * 要乘以的系数
457   * @return 将i行i列之前数字置换为0后的新的行
458   */
459   public int[] addValue(int[] currentRow, int[] frontRow, int ratio) throws Exception {
460     for (int i = 0; i < currentRow.length; i++) {
461       currentRow[i] += frontRow[i] * ratio;
462     }
463     return currentRow;
464   }
465 
466  
467 
468   /**
469   * 指定列的位置是否为0,查找第一个不为0的位置的行进行位置调换,如果没有则返回原来的值
470   * 
471   * @param determinant
472   * 需要处理的行列式
473   * @param line
474   * 要调换的行
475   * @param row
476   * 要判断的列
477   */
478   public int[][] changeDeterminantNoZero(int[][] determinant, int line, int row) throws Exception {
479     for (int j = line; j < determinant.length; j++) {
480       // 进行行调换
481       if (determinant[j][row] != 0) {
482         int[] temp = determinant[line];
483         determinant[line] = determinant[j];
484         determinant[j] = temp;
485         return determinant;
486       }
487     }
488     return determinant;
489   }
490 
491  
492 
493 }

2、测试矩阵的一般性质:MatrixTest.java

 1 package cn.com.zfc.help;
 2 
 3 import java.util.Map;
 4 import java.util.Map.Entry;
 5 import java.util.Scanner;
 6 import java.util.Set;
 7 
 8 /**
 9 * 
10 * @title MatrixTest
11 * @describe 测试矩阵
12 * @author 张富昌
13 * @date 2017年4月6日下午1:08:58
14 */
15 public class MatrixTest {
16   public static void main(String[] args) {
17     Scanner scanner = new Scanner(System.in);
18     // 创建第一个矩阵
19     System.out.println("请输入第一个矩阵的行数:");
20     int row = scanner.nextInt();
21     System.out.println("请输入第一个矩阵的列数:");
22     int cel = scanner.nextInt();
23     Matrix matrix1 = new Matrix(row, cel);
24     // 初始化矩阵
25     matrix1.initMatrix();
26 
27     System.out.println("第一个矩阵为:");
28     matrix1.printMatrix();
29     matrix1.showType();
30 
31     // 矩阵转置
32     Matrix matrix = matrix1.reverse(matrix1);
33     System.out.println("转置之后的结果:");
34     matrix.printMatrix();
35     matrix1.showType();
36 
37     // 矩阵中的最大元素
38     int max = matrix1.getMaxNumber(matrix1);
39     System.out.println("矩阵中的最大元素:" + max);
40     matrix1.showType();
41 
42     // 矩阵中的最小元素
43     int min = matrix1.getMinNumber(matrix1);
44     System.out.println("矩阵中的最小元素:" + min);
45     matrix1.showType();
46 
47     // 每一行的最大值
48     int[] maxs = matrix1.getEachRowMax(matrix1);
49     for (int i = 0; i < maxs.length; i++) {
50       System.out.println("第" + (i + 1) + "行的最大值是:" + maxs[i]);
51     }
52     matrix1.showType();
53 
54     // 每一列的最小值
55     int[] mins = matrix1.getEachCelMin(matrix1);
56     for (int i = 0; i < mins.length; i++) {
57       System.out.println("第" + (i + 1) + "列的最小值是:" + mins[i]);
58     }
59     matrix1.showType();
60 
61     // 排序
62     Matrix m = matrix1.sort(matrix1);
63     System.out.println("排序之后的结果:");
64     m.printMatrix();
65     matrix1.showType();
66 
67     // 找矩阵中的元素以及其个数
68     System.out.println("矩阵中的元素以及其个数如下:");
69     Map<Integer, Integer> map = matrix1.getElementAndCount(matrix1);
70     Set<Entry<Integer, Integer>> set = map.entrySet();
71     for (Entry<Integer, Integer> entry : set) {
72       int element = entry.getKey();
73       int count = entry.getValue();
74       System.out.println("元素 " + element + " 有" + count + " 个");
75     }
76     matrix1.showType();
77 
78   }
79 }

3、测试矩阵相加:AddMatrix.java

 1 package cn.com.zfc.help;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6 * 
 7 * @title AddMatrix
 8 * @describe 计算矩阵相加
 9 * @author 张富昌
10 * @date 2017年4月6日下午12:59:43
11 */
12 public class AddMatrix {
13   public static void main(String[] args) {
14     Scanner scanner = new Scanner(System.in);
15     // 创建第一个矩阵
16     System.out.println("请输入第一个矩阵的行数:");
17     int row = scanner.nextInt();
18     System.out.println("请输入第一个矩阵的列数:");
19     int cel = scanner.nextInt();
20     Matrix matrix1 = new Matrix(row, cel);
21     // 初始化矩阵
22     matrix1.initMatrix();
23 
24     System.out.println("第一个矩阵为:");
25     matrix1.printMatrix();
26     matrix1.showType();
27 
28     // 创建第二个矩阵
29     System.out.println("请输入第二个矩阵的行数:");
30     row = scanner.nextInt();
31     System.out.println("请输入第二个矩阵的列数:");
32     cel = scanner.nextInt();
33     Matrix matrix2 = new Matrix(row, cel);
34     // 初始化矩阵
35     matrix2.initMatrix();
36     System.out.println("第二个矩阵为:");
37     matrix2.printMatrix();
38     matrix1.showType();
39 
40     // 两个矩阵相加(两个矩阵的行数和列数要一致)
41     Matrix m = matrix1.addMatrix(matrix1, matrix2);
42     System.out.println("两个矩阵相加之后的结果矩阵:");
43     if (m != null) {
44       m.printMatrix();
45       matrix1.showType();
46     } else {
47       System.out.println("两个矩阵的行数和列数不一致");
48     }
49   }
50 }

4、测试矩阵相乘:MulMatrix.java

 1 package cn.com.zfc.help;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6 * 
 7 * @title MulMatrix
 8 * @describe 两矩阵相乘
 9 * @author 张富昌
10 * @date 2017年4月6日下午1:04:08
11 */
12 public class MulMatrix {
13   public static void main(String[] args) {
14     Scanner scanner = new Scanner(System.in);
15     // 创建第一个矩阵
16     System.out.println("请输入第一个矩阵的行数:");
17     int row = scanner.nextInt();
18     System.out.println("请输入第一个矩阵的列数:");
19     int cel = scanner.nextInt();
20     Matrix matrix1 = new Matrix(row, cel);
21     // 初始化矩阵
22     matrix1.initMatrix();
23 
24     System.out.println("第一个矩阵为:");
25     matrix1.printMatrix();
26     matrix1.showType();
27 
28     // 创建第二个矩阵
29     System.out.println("请输入第二个矩阵的行数:");
30     row = scanner.nextInt();
31     System.out.println("请输入第二个矩阵的列数:");
32     cel = scanner.nextInt();
33     Matrix matrix2 = new Matrix(row, cel);
34     // 初始化矩阵
35     matrix2.initMatrix();
36     System.out.println("第二个矩阵为:");
37     matrix2.printMatrix();
38     matrix1.showType();
39 
40     // 两个矩阵相乘(第一个矩阵的列数和第二个矩阵的行数要一致)
41     Matrix m = matrix1.mulMatrix(matrix1, matrix2);
42     System.out.println("两个矩阵相乘之后的结果矩阵:");
43     if (m != null) {
44       m.printMatrix();
45       m.printMatrix();
46     } else {
47       System.out.println("第一个矩阵的列数和第二个矩阵的行数不一致");
48     }
49   }
50 }

5、测试行列式计算:CalculateMatrix.java

 1 package cn.com.zfc.help;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6 * 
 7 * @title CalculateMatrix
 8 * @describe 计算行列式
 9 * @author 张富昌
10 * @date 2017年4月6日下午1:08:40
11 */
12 public class CalculateMatrix {
13   public static void main(String[] args) {
14     Scanner scanner = new Scanner(System.in);
15     // 创建第一个矩阵
16     System.out.println("请输入第一个矩阵的行数:");
17     int row = scanner.nextInt();
18     System.out.println("请输入第一个矩阵的列数:");
19     int cel = scanner.nextInt();
20     Matrix matrix1 = new Matrix(row, cel);
21     // 初始化矩阵
22     matrix1.initMatrix();
23 
24     System.out.println("第一个矩阵为:");
25     matrix1.printMatrix();
26     matrix1.showType();
27 
28     // 计算行列式
29     int result;
30     try {
31       result = matrix1.mathDeterminantCalculation(matrix1.getMatrix());
32       System.out.println("方阵行列式的结果是:" + result);
33     } catch (Exception e) {
34       System.out.println("不是正确的行列式!!");
35     }
36   }
37 }
原文地址:https://www.cnblogs.com/zfc-java/p/6673033.html