曾几何时,
是它,
是它,
就是它,
在数学课堂上,
一直折磨得我们死去活来,
对,
你没猜错,
它就是我们今天要讲的行列式。
行列式这玩意儿,
怎么说嘞,
说难吧,确实也不是很难,
说不难吧,其实也挺难的,
不说别的,
就瞧瞧它的计算量吧,
一个5阶的行列式,就有120项,
所以,今天我们要说的
就是行列式的编程计算。
话不多说,直接上代码:
(你好,我才叫代码,楼上的什么鬼闪开好嘛。)
import java.text.DecimalFormat;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
while(1==1){
//input
Scanner sc = new Scanner(System.in);
System.out.println("请输入行列式的阶数:");
int n = sc.nextInt();
//System.out.println(n);
double [][]test= new double[n][n];
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++){
System.out.println("请输入第 "+(i+1)+"行 "+(j+1)+"列的数 ");
test[i][j]=sc.nextDouble();
//System.out.println(det[i]);
}
}
//display
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++){
System.out.print(test[i][j]+" ");
}
System.out.println("");
}
//calculate
double result;
try {
result = mathDeterminantCalculation(test);
System.out.println(result);
} catch (Exception e) {
System.out.println("不是正确的行列式!!");
}
}
}
/***
* 求行列式的算法
* @param value 需要算的行列式
* @return 计算的结果
*/
public static double mathDeterminantCalculation(double[][] 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时
double 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) {
double[] temp = value[i];
value[i] = value[i-1];
value[i-1] = temp;
result*=-1;
continue;
}
double ratio = -(value[i][j]/value[j][j]);
value[i] = addValue(value[i],value[j],ratio);
}
}
DecimalFormat df = new DecimalFormat(".##");
return Double.parseDouble(df.format(mathValue(value,result)));
}
/**
* 计算行列式的结果
* @param value
* @return
*/
public static double mathValue(double[][] value,double 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 static double[] addValue(double[] currentRow,double[] frontRow, double 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 static double[][] changeDeterminantNoZero(double[][] determinant,int line,int row)throws Exception{
for (int j = line; j < determinant.length; j++) {
//进行行调换
if (determinant[j][row] != 0) {
double[] temp = determinant[line];
determinant[line] = determinant[j];
determinant[j] = temp;
return determinant;
}
}
return determinant;
}
}