首页 > 代码库 > JavaSE基础之矩阵运算

JavaSE基础之矩阵运算

JavaSE基础之矩阵运算

1、矩阵类:Matrix.java

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

 

package cn.com.zfc.help;

 

import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

 

/**
*
* @title Matrix
* @describe 矩阵运算
* @author 张富昌
* @date 2017年3月21日下午6:45:00
*/
public class Matrix {
  // 使用二维数组模拟矩阵
  private int[][] matrix;
  private int row;
  private int cel;

 

  /**
  * 构造方法
  *
  * @param row:矩阵的行数
  * @param cel:矩阵的列数
  */
  public Matrix(int row, int cel) {
    this.row = row;
    this.cel = cel;
    // 初始化数组
    matrix = new int[this.row][this.cel];
  }

 

  // 为私有属性添加 setter()和getter()方法:赋值,取值
  public int getRow() {
    return row;
  }

 

  public void setRow(int row) {
    this.row = row;
  }

 

  public int getCel() {
    return cel;
  }

 

  public void setCel(int cel) {
    this.cel = cel;
  }

 

  public int[][] getMatrix() {
    return matrix;
  }

 

  public void setMatrix(int[][] matrix) {
    this.matrix = matrix;
  }

 

  /**
  * 快速初始化矩阵中的成员变量:二维数组
  */
  public void initMatrix() {
    Scanner scanner = new Scanner(System.in);
    for (int i = 0; i < this.getRow(); i++) {
      for (int j = 0; j < this.getCel(); j++) {
        // 自己输入
        // matrix[i][j] = scanner.nextInt();
        // 生成一个 0-100 的随机数
        matrix[i][j] = (int) (Math.random() * 100 + 1);
        // 在测试矩阵中元素的种类及其个数时,不用随机赋值,即注释上一行代码
        // matrix[i][j] = i;
      }
    }
  }

 

  /**
  * 输出矩阵
  */
  public void printMatrix() {
    for (int i = 0; i < this.getRow(); i++) {
      for (int j = 0; j < this.getCel(); j++) {
        System.out.print(matrix[i][j] + "\t");
      }
      System.out.println();
    }
  }

 

  /**
  *
  * @param matrix1:第一个矩阵
  * @param matrix2:第二个矩阵
  * @return:两个矩阵相加之后的矩阵
  */
  public Matrix addMatrix(Matrix matrix1, Matrix matrix2) {
    if ((matrix1.getRow() == matrix2.getRow()) && (matrix1.getCel() == matrix2.getCel())) {
      // 中间矩阵,相加之后的结果
      Matrix m = new Matrix(matrix1.getRow(), matrix2.getCel());

 

      for (int i = 0; i < m.getRow(); i++) {
        for (int j = 0; j < m.getCel(); j++) {
          m.getMatrix()[i][j] = matrix1.getMatrix()[i][j] + matrix2.getMatrix()[i][j];
        }
      }
      return m;
    } else {
      return null;
    }

 

  }

 

  /**
  *
  * @param matrix1:第一个矩阵
  * @param matrix2:第二个矩阵
  * @return:两个矩阵相乘之后的矩阵
  */
  public Matrix mulMatrix(Matrix matrix1, Matrix matrix2) {
    if (matrix1.getRow() == matrix2.getCel()) {

 

      Matrix m = new Matrix(matrix1.getRow(), matrix2.getCel());

 

      for (int i = 0; i < matrix1.getRow(); i++) {
        for (int j = 0; j < matrix2.getCel(); j++) {
          int sum = 0;
          for (int k = 0; k < matrix1.getCel(); k++) {
            sum += matrix1.getMatrix()[i][k] * matrix2.getMatrix()[k][j];
          }
          m.getMatrix()[i][j] = sum;
        }
      }
      return m;
    } else {
      return null;
    }
  }

 

  /**
  * 矩阵转置
  *
  * @param matrix
  * @return 转置后的矩阵
  */
  public Matrix reverse(Matrix matrix) {

 

    Matrix m = new Matrix(matrix.getCel(), matrix.getRow());

 

    for (int i = 0; i < m.getCel(); i++) {

 

      for (int j = 0; j < m.getRow(); j++) {

 

        m.getMatrix()[j][i] = matrix.getMatrix()[i][j];
      }
    }
    return m;
  }

 

  /**
  *
  * @param matrix
  * @return:返回最大的值
  */
  public int getMaxNumber(Matrix matrix) {
    // 设置假设的默认的最大值(一般不是)
    int max = matrix.getMatrix()[0][0];

 

    for (int i = 0; i < matrix.getRow(); i++) {
      for (int j = 0; j < matrix.getCel(); j++) {
        if (max < matrix.getMatrix()[i][j]) {
          max = matrix.getMatrix()[i][j];
        }
      }
    }
    return max;
  }

 

  /**
  *
  * @param matrix
  * @return:返回最小的值
  */
  public int getMinNumber(Matrix matrix) {
    int min = matrix.getMatrix()[0][0];
    for (int i = 0; i < matrix.getRow(); i++) {
      for (int j = 0; j < matrix.getCel(); j++) {
        if (min > matrix.getMatrix()[i][j]) {
          min = matrix.getMatrix()[i][j];
        }
      }
    }
    return min;
  }

 

  /**
  *
  * @param matrix
  * @return:每一行元素的最大值组成的数组
  */
  public int[] getEachRowMax(Matrix matrix) {
    int[] arr = new int[matrix.getRow()];
    for (int i = 0; i < matrix.getRow(); i++) {
      // 找出每一行的最大值
      // 中间变量
      int temp = matrix.getMatrix()[i][0];
      for (int j = 0; j < matrix.getCel(); j++) {
        if (temp < matrix.getMatrix()[i][j]) {
          temp = matrix.getMatrix()[i][j];
        }
      }
      arr[i] = temp;
    }
    return arr;
  }

 

  /**
  *
  * @param matrix
  * @return:每一行的最小值
  */
  public int[] getEachRowMin(Matrix matrix) {
    int[] arr = new int[matrix.getRow()];
    for (int i = 0; i < matrix.getRow(); i++) {
      // 找出每一行的最小值
      // 中间变量
      int temp = matrix.getMatrix()[i][0];
      for (int j = 0; j < matrix.getCel(); j++) {
        if (temp > matrix.getMatrix()[i][j]) {
          temp = matrix.getMatrix()[i][j];
        }
      }
      arr[i] = temp;
     }
    return arr;
   }

 

  /**
  *
  * @param matrix
  * @return:每一列元素的最小值组成的数组
  */
  public int[] getEachCelMin(Matrix matrix) {
    // 先转置
    Matrix m = matrix.reverse(matrix);
    // 后求每一行的最小值
    int[] arr = m.getEachRowMin(m);
    return arr;
  }

 

  public Matrix sort(Matrix matrix) {
    Matrix m = new Matrix(matrix.getRow(), matrix.getCel());
    m.setMatrix(matrix.getMatrix());
    // 中间变量,用来存放矩阵的元素
    int[] arr = new int[m.getRow() * m.getCel()];
    int count = 0;
    // 将二维数组转化为一维数组
    for (int i = 0; i < m.getRow(); i++) {
      for (int j = 0; j < m.getCel(); j++) {
        arr[count] = m.getMatrix()[i][j];
        count++;
      }
    }
    // 对一维数组进行排序:冒泡排序
    arr = bubbleSort(arr);
    for (int i = 0; i < m.getRow(); i++) {
      for (int j = 0; j < m.getCel(); j++) {
        count--;
        m.getMatrix()[i][j] = arr[count];
      }
    }
    return m;
  }

 

  /**
  *
  * 功能:冒泡排序的基本思想就是不断比较相邻的两个数,让较大的元素不断地往后移。经过一轮比较,就选出最大的数;经过第2轮比较,就选出次大的数,
  * 以此类推。
  *
  *
  * 参数:int[] array
  *
  * 返回类型:int[]
  */
  public int[] bubbleSort(int[] array) {
    // 使用临时数组,替代原始数组
    int[] arr = array;
    for (int i = 0; i < arr.length; i++) {
      for (int j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] < arr[j + 1]) {
          int temp = arr[j];
          arr[j] = arr[j + 1];
          arr[j + 1] = temp;
        }
      }
    }
    return arr;
  }

 

  public Map<Integer, Integer> getElementAndCount(Matrix matrix) {
    // 存放的是键值对, 1-3 ,2-4
    Map<Integer, Integer> map = new HashMap<>();
    // 判断重复的元素
    Set<Integer> set = new HashSet<>();
    for (int i = 0; i < matrix.getRow(); i++) {
      for (int j = 0; j < matrix.getCel(); j++) {
        if (set.add(matrix.getMatrix()[i][j])) {
          map.put(matrix.getMatrix()[i][j], 1);
        } else {
          map.replace(matrix.getMatrix()[i][j], map.get(matrix.getMatrix()[i][j]) + 1);
        }
      }
    }
    return map;
  }

 

  public void showType() {
    System.out.println("-------------------------------------");
  }

 

  /***
  * 求行列式的算法
  *
  * @param value
  * 需要算的行列式
  * @return 计算的结果
  */
  public int mathDeterminantCalculation(int[][] value) throws Exception {
    if (value.length == 1) {
      // 当行列式为1阶的时候就直接返回本身
      return value[0][0];
    } else if (value.length == 2) {
      // 如果行列式为二阶的时候直接进行计算
      return value[0][0] * value[1][1] - value[0][1] * value[1][0];
    }
    // 当行列式的阶数大于2时
    int result = 1;
    for (int i = 0; i < value.length; i++) {
      // 检查数组对角线位置的数值是否是0,如果是零则对该数组进行调换,查找到一行不为0的进行调换
      if (value[i][i] == 0) {
        value = http://www.mamicode.com/changeDeterminantNoZero(value, i, i);
        result *= -1;
      }
      for (int j = 0; j < i; j++) {
        // 让开始处理的行的首位为0处理为三角形式
        // 如果要处理的列为0则和自己调换一下位置,这样就省去了计算
        if (value[i][j] == 0) {
          continue;
        }
        // 如果要是要处理的行是0则和上面的一行进行调换
        if (value[j][j] == 0) {
          int[] temp = value[i];
          value[i] = value[i - 1];
          value[i - 1] = temp;
          result *= -1;
          continue;
        }
        int ratio = -(value[i][j] / value[j][j]);
        value[i] = addValue(value[i], value[j], ratio);
      }
    }
    DecimalFormat df = new DecimalFormat(".##");
    return Integer.parseInt(df.format(mathValue(value, result)));
  }

 

  /**
  * 计算行列式的结果
  *
  * @param value
  * @return
  */
  public int mathValue(int[][] value, int result) throws Exception {
    for (int i = 0; i < value.length; i++) {
      // 如果对角线上有一个值为0则全部为0,直接返回结果
      if (value[i][i] == 0) {
        return 0;
      }
      result *= value[i][i];
    }
    return result;
  }

 

  /***
  * 将i行之前的每一行乘以一个系数,使得从i行的第i列之前的数字置换为0
  *
  * @param currentRow
  * 当前要处理的行
  * @param frontRow
  * i行之前的遍历的行
  * @param ratio
  * 要乘以的系数
  * @return 将i行i列之前数字置换为0后的新的行
  */
  public int[] addValue(int[] currentRow, int[] frontRow, int ratio) throws Exception {
    for (int i = 0; i < currentRow.length; i++) {
      currentRow[i] += frontRow[i] * ratio;
    }
    return currentRow;
  }

 

  /**
  * 指定列的位置是否为0,查找第一个不为0的位置的行进行位置调换,如果没有则返回原来的值
  *
  * @param determinant
  * 需要处理的行列式
  * @param line
  * 要调换的行
  * @param row
  * 要判断的列
  */
  public int[][] changeDeterminantNoZero(int[][] determinant, int line, int row) throws Exception {
    for (int j = line; j < determinant.length; j++) {
      // 进行行调换
      if (determinant[j][row] != 0) {
        int[] temp = determinant[line];
        determinant[line] = determinant[j];
        determinant[j] = temp;
        return determinant;
      }
    }
    return determinant;
  }

 

}

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

package cn.com.zfc.help;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;

/**
*
* @title MatrixTest
* @describe 测试矩阵
* @author 张富昌
* @date 2017年4月6日下午1:08:58
*/
public class MatrixTest {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    // 创建第一个矩阵
    System.out.println("请输入第一个矩阵的行数:");
    int row = scanner.nextInt();
    System.out.println("请输入第一个矩阵的列数:");
    int cel = scanner.nextInt();
    Matrix matrix1 = new Matrix(row, cel);
    // 初始化矩阵
    matrix1.initMatrix();

    System.out.println("第一个矩阵为:");
    matrix1.printMatrix();
    matrix1.showType();

    // 矩阵转置
    Matrix matrix = matrix1.reverse(matrix1);
    System.out.println("转置之后的结果:");
    matrix.printMatrix();
    matrix1.showType();

    // 矩阵中的最大元素
    int max = matrix1.getMaxNumber(matrix1);
    System.out.println("矩阵中的最大元素:" + max);
    matrix1.showType();

    // 矩阵中的最小元素
    int min = matrix1.getMinNumber(matrix1);
    System.out.println("矩阵中的最小元素:" + min);
    matrix1.showType();

    // 每一行的最大值
    int[] maxs = matrix1.getEachRowMax(matrix1);
    for (int i = 0; i < maxs.length; i++) {
      System.out.println("第" + (i + 1) + "行的最大值是:" + maxs[i]);
    }
    matrix1.showType();

    // 每一列的最小值
    int[] mins = matrix1.getEachCelMin(matrix1);
    for (int i = 0; i < mins.length; i++) {
      System.out.println("第" + (i + 1) + "列的最小值是:" + mins[i]);
    }
    matrix1.showType();

    // 排序
    Matrix m = matrix1.sort(matrix1);
    System.out.println("排序之后的结果:");
    m.printMatrix();
    matrix1.showType();

    // 找矩阵中的元素以及其个数
    System.out.println("矩阵中的元素以及其个数如下:");
    Map<Integer, Integer> map = matrix1.getElementAndCount(matrix1);
    Set<Entry<Integer, Integer>> set = map.entrySet();
    for (Entry<Integer, Integer> entry : set) {
      int element = entry.getKey();
      int count = entry.getValue();
      System.out.println("元素 " + element + " 有" + count + " 个");
    }
    matrix1.showType();

  }
}

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

package cn.com.zfc.help;

import java.util.Scanner;

/**
*
* @title AddMatrix
* @describe 计算矩阵相加
* @author 张富昌
* @date 2017年4月6日下午12:59:43
*/
public class AddMatrix {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    // 创建第一个矩阵
    System.out.println("请输入第一个矩阵的行数:");
    int row = scanner.nextInt();
    System.out.println("请输入第一个矩阵的列数:");
    int cel = scanner.nextInt();
    Matrix matrix1 = new Matrix(row, cel);
    // 初始化矩阵
    matrix1.initMatrix();

    System.out.println("第一个矩阵为:");
    matrix1.printMatrix();
    matrix1.showType();

    // 创建第二个矩阵
    System.out.println("请输入第二个矩阵的行数:");
    row = scanner.nextInt();
    System.out.println("请输入第二个矩阵的列数:");
    cel = scanner.nextInt();
    Matrix matrix2 = new Matrix(row, cel);
    // 初始化矩阵
    matrix2.initMatrix();
    System.out.println("第二个矩阵为:");
    matrix2.printMatrix();
    matrix1.showType();

    // 两个矩阵相加(两个矩阵的行数和列数要一致)
    Matrix m = matrix1.addMatrix(matrix1, matrix2);
    System.out.println("两个矩阵相加之后的结果矩阵:");
    if (m != null) {
      m.printMatrix();
      matrix1.showType();
    } else {
      System.out.println("两个矩阵的行数和列数不一致");
    }
  }
}

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

package cn.com.zfc.help;

import java.util.Scanner;

/**
*
* @title MulMatrix
* @describe 两矩阵相乘
* @author 张富昌
* @date 2017年4月6日下午1:04:08
*/
public class MulMatrix {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    // 创建第一个矩阵
    System.out.println("请输入第一个矩阵的行数:");
    int row = scanner.nextInt();
    System.out.println("请输入第一个矩阵的列数:");
    int cel = scanner.nextInt();
    Matrix matrix1 = new Matrix(row, cel);
    // 初始化矩阵
    matrix1.initMatrix();

    System.out.println("第一个矩阵为:");
    matrix1.printMatrix();
    matrix1.showType();

    // 创建第二个矩阵
    System.out.println("请输入第二个矩阵的行数:");
    row = scanner.nextInt();
    System.out.println("请输入第二个矩阵的列数:");
    cel = scanner.nextInt();
    Matrix matrix2 = new Matrix(row, cel);
    // 初始化矩阵
    matrix2.initMatrix();
    System.out.println("第二个矩阵为:");
    matrix2.printMatrix();
    matrix1.showType();

    // 两个矩阵相乘(第一个矩阵的列数和第二个矩阵的行数要一致)
    Matrix m = matrix1.mulMatrix(matrix1, matrix2);
    System.out.println("两个矩阵相乘之后的结果矩阵:");
    if (m != null) {
      m.printMatrix();
      m.printMatrix();
    } else {
      System.out.println("第一个矩阵的列数和第二个矩阵的行数不一致");
    }
  }
}

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

package cn.com.zfc.help;

import java.util.Scanner;

/**
*
* @title CalculateMatrix
* @describe 计算行列式
* @author 张富昌
* @date 2017年4月6日下午1:08:40
*/
public class CalculateMatrix {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    // 创建第一个矩阵
    System.out.println("请输入第一个矩阵的行数:");
    int row = scanner.nextInt();
    System.out.println("请输入第一个矩阵的列数:");
    int cel = scanner.nextInt();
    Matrix matrix1 = new Matrix(row, cel);
    // 初始化矩阵
    matrix1.initMatrix();

    System.out.println("第一个矩阵为:");
    matrix1.printMatrix();
    matrix1.showType();

    // 计算行列式
    int result;
    try {
      result = matrix1.mathDeterminantCalculation(matrix1.getMatrix());
      System.out.println("方阵行列式的结果是:" + result);
    } catch (Exception e) {
      System.out.println("不是正确的行列式!!");
    }
  }
}

 

JavaSE基础之矩阵运算