JavaSE基础之矩阵运算
Posted 勇闯天涯zfc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 = 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基础之矩阵运算的主要内容,如果未能解决你的问题,请参考以下文章