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 }