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基础之矩阵运算的更多相关文章

  1. javaSE基础07

    javaSE基础07 一.static静态修饰符 用了static修饰的变量就会变成共享的属性,只会初始化一次,在内存中只存在一个,并且每个对象都可以访问,存放在方法区(数据共享区) 1.1 stat ...

  2. javaSE基础06

    javaSE基础06 一.匿名对象 没有名字的对象,叫做匿名对象. 1.2匿名对象的使用注意点: 1.我们一般不会用匿名对象给属性赋值的,无法获取属性值(现阶段只能设置和拿到一个属性值.只能调用一次方 ...

  3. javaSE基础05

    javaSE基础05:面向对象 一.数组 数组的内存管理 : 一块连续的空间来存储元素. Int [ ] arr = new int[ ]; 创建一个int类型的数组,arr只是一个变量,只是数组的一 ...

  4. javaSE基础04

    javaSE基础04 一.三木运算符 <表达式1> ? <表达式2> : <表达式3> "?"运算符的含义是: 先求表达式1的值, 如果为真, ...

  5. javaSE基础03

    javaSE基础03 生活中常见的进制:十进制(0-9).星期(七进制(0-6)).时间(十二进制(0-11)).二十四进制(0-23) 进制之间的转换: 十进制转为二进制: 将十进制除以2,直到商为 ...

  6. javaSE基础02

    javaSE基础02 一.javac命令和java命令做什么事情? javac:负责编译,当执行javac时,会启动java的编译程序,对指定扩展名的.java文件进行编译,生成了jvm可以识别的字节 ...

  7. JavaSE基础01

    JavaSE基础篇01 ------从今天开始,我就学习正式java了,O(∩_∩)O哈哈~,请大家多指教哦 一.Windows常见的dos命令 操作dos命令: win7 --->开始 --- ...

  8. javase基础复习攻略《十》

    按照计划本篇为大家总结JAVA的网络编程,什么叫网络编程呢?网络编程!=网站编程,对于这一点大家一定要注意,很多小朋友都曾经这么认为.既然谈到网络编程,咱们先了解一下网络的基础知识,什么是计算机网络? ...

  9. javase基础复习攻略《二》

    今天就开始的真正走进JAVASE的世界,本篇介绍的是:JAVASE基础语法,大家如果有C语言的基础,对于本节内容一定感觉非常轻松,编程语言之间的都是相通的,只不过C语言属于面向过程编程,而JAVA语言 ...

随机推荐

  1. ORB_SLAM2 源码阅读 ORB_SLAM2::Initializer::ComputeF21 (OpenCV 细节)

    ORB_SLAM2 计算 F21 的代码是这样的. cv::Mat Initializer::ComputeF21(const vector<cv::Point2f> &vP1,c ...

  2. elasticsearch-head插件安装的一些坑!es6.5.4版本

    折腾了一晚上,总算成功了!,大部分坑都记录了下来,版本升级太快真实个大坑,每个版本都不一样,学的心累!! 这坑太多了!主要就是以下几点最主要的: 因为我这里只使用hear安装,不使用哪个打包工具,所以 ...

  3. asp.net操作word 配置在IIS上出现的问题

    异常: 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 ...

  4. URIEncoding与useBodyEncodingForURI 在tomcat中文乱码处理上的区别

    大家知道tomcat5.0开始,对网页的中文字符的post或者get,经常会出现乱码现象. 具体是因为Tomcat默认是按ISO-8859-1进行URL解码,ISO-8859-1并未包括中文字符,这样 ...

  5. python基础-类的其他方法

    一.isinstance(obj,cls)检查是否obj是类的cls对象 # -*- coding:utf-8 -*- __author__ = 'shisanjun' class Foo(objec ...

  6. GBDT+LR simple例子

    卧槽,本来猜GBDT获取的组合特征,需要自己去解析GBDT的树,scikit learn里面竟然直接调用apply函数就可以了 # 弱分类器的数目 n_estimator = 10 # 随机生成分类数 ...

  7. mybatis 易百练习笔记

    1. session.commit()  增删改需要提交     session.close()    session需要关闭 2. insert  into t()   values()  不用写i ...

  8. HDU 2476 String painter(区间DP+思维)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意:给你字符串A.B,每次操作可以将一段区间刷成任意字符,问最少需要几次操作可以使得字符串 ...

  9. es6遍历数组forof

  10. sqlserver中的循环遍历(普通循环和游标循环)(转载)

    sql 经常用到循环,下面介绍一下普通循环和游标循环 1.首先需要一个测试表数据Student