參考了:https://blog.csdn.net/u011885865/article/details/42032229
需要的基礎:學過《線性代數》,知道行列式值的求法
基本公式:對於如下的行列式:

其值為:

相信大家都懂這個公式的具體含義,我就不解釋了,不懂的同學百度一下行列式
分析一個這個公式該如何實現:
假定現有有一個3*3的行列式,則其計算公式為:

觀察這個式子,可以發現其有一個核心,那就是生成一個全排列。本例中是一個3*3矩陣,因此需要生成123的全排列,共有六個:123、132、213、231、321、312。
然后就是要計算,生成的排列的逆序數,即

總結起來可分為如下幾步:
1、求出給定n階矩陣的全排列,我用vector<int>存儲一個全排列(即上例中6個全排列中的某一個),用vector<vector<int> >存儲所有的全排列(即上例中的六個全排列)。
2、計算排列的逆序數。
3、分別以1,2...n為row值,從vector<int>中依次提取的值為col值,組成行列式中元素的下標,然后相乘
4、求和。
算法實現:
1、求全排的算法如下,不懂該算法的可以移步:https://www.cnblogs.com/XiaoXiaoShuai-/p/10383535.html
//交換元素
void swap(vector<int>& vec, int i, int j)
{
int temp = vec[i];
vec[i] = vec[j];
vec[j] = temp;
}
//第一個參數表示初始的數列,在上例中,該vec中的元素為1,2,3
//第二個參數表示最終得到的全排列集合
void Perm(vector<int>& vec, vector<vector<int> >& vec_seq, int current_index = 0)
{
if (current_index == ((int)vec.size() - 1))
{
vec_seq.push_back(vec);
}
else
{
for (int i = current_index; i < (int)vec.size(); i++)
{
swap(vec, i, current_index);
Perm(vec, vec_seq, current_index + 1);
swap(vec, i, current_index);
}
}
}
當然,還得有一個生成初始數列的函數
//根據n生成一個初始vector
vector<int> inivec(int n)
{
vector<int> vec;
for (int i = 0; i < n; i++)
vec.push_back(i);
return vec;
}
第二步:求出全排列的逆序數,判斷逆序數的奇偶
//得出排列的逆排序數,並根據奇偶判讀正負
bool Iseven(int num)
{
//用位與運算來判斷奇偶(最快的判斷奇偶的方法)
return ((num & 1) == 0);
}
//是否冪為正
bool PowerIsPosition(vector<int>& vec)
{
//count即為逆序數,初始化為0
int count = 0;
for (int i = 0; i < (int)vec.size(); i++)
{
for (int j = i + 1; j < (int)vec.size(); j++)
{
if (vec[i] > vec[j])
{
count += 1;
}
}
}
return (Iseven(count));
}
第三步和第四步:
//計算結果
//第一個參數表示輸入的行列式
//第二個參數表示該行列式的階數,在本例中n = 3,即一個3*3的行列式
int calculate(int** array, int n)
{
vector<vector<int> > vec_que;
vector<int> vec = inivec(n);
vector<int> vec_elem;
Perm(vec, vec_que);
//最終結果,初始化為0
int result = 0;
//依次為vec_que中取出行列式
for (int i = 0; i < (int)vec_que.size();i++)
{
vec_elem = vec_que[i];
//mi即為前面(-1)的n次冪,最后結果為-1或者1
int mi = PowerIsPosition(vec_elem) ? 1 : (-1);
int temp = mi;
//row號初始化為0之后依次加1
int row = 0;
//col號依次從vec_elem中取出
for (int j = 0; j < (int)vec_elem.size();j++)
{
int col = vec_elem[j];
temp *= array[row++][col];
}
result += temp;
}
return result;
}
檢驗一下:
int main()
{
int** array = new int*[3];
for (int i = 0; i < 3; i++)
{
array[i] = new int[3];
}
array[0][0] = 2;
array[0][1] = -4;
array[0][2] = 1;
array[1][0] = 1;
array[1][1] = -5;
array[1][2] = 3;
array[2][0] = 1;
array[2][1] = -1;
array[2][2] = 1;
int result = calculate(array, 3);
return 0;
}
計算的result = -8,結果正確
