zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Python面向对象详解
    使用树莓派搭建LoRaWAN网关并接入腾讯云物联网开发平台
    dajngo
    dajngo 项目目录结构调整
    Django
    nacos的简单使用
    MySQL数据库开发规范
    mabatis的sql标签
    直接插入100w数据报错
    大数据量插入到数据库
  • 原文地址:https://www.cnblogs.com/zfc-java/p/6673033.html
Copyright © 2011-2022 走看看