我写了一个递归函数来计算行列式。我知道我本可以更有效地做到这一点,但这不是这里的重点。我有一个名为"det1"的变量,它在递归结束时保存行列式的最终值。 奇怪的是,当我在 det 函数中返回这个值时,我得到了完全的垃圾。但是,当我简单地打印"det1"时,我得到了答案。这里有什么猜测吗?
int det1 = 0;
int p = 0;
int det(vector<vector<int> > (&A)){
if (A.size() != A[0].size()){
cout << "Determinant Error: non-square matrix. n";
return 0;
}
int cF;
vector<vector<int> > temp01;
if (A.size() == 2){
det1 += (A[0][0]*A[1][1]-A[0][1]*A[1][0]);
//cout << "Determinant : " << det1 << "n";
int output = det1; ///////////////////////////////////////Problem with final return
//cout << "Recursion Count : " << p << "n";
//return(output); ///////////////////////////////////////
}else{//extract until a 2x2 is reached
for (int i = 0; i < A.size(); i++){
temp01 = extractNext(A,0, i);
//printMatrix(temp01);
cF = pow(-1, (0)+(i))*A[0][i];
//cout << "Cofactor : " << cF << "n";
for (int j = 0; j< temp01.size(); j++){
temp01[0][j] = cF*temp01[0][j]; //account for cofactor by multiplying it in
}
//printMatrix(temp); cout << "n";
p++;
det(temp01);
}
}
}
您不会在所有代码路径上返回值,当您使用从未存在的返回值时,这最终会导致未定义的行为。
(一个相当现代的编译器应该警告你这一点。
您应该从递归中返回行列式,而不是改变全局 - 混合可变状态和递归通常只会导致麻烦。
(这也使您的代码与行列式的数学定义更加相似,这反过来又使其更易于理解和验证。
通过一些小的更改,我会建议类似
int det(const vector<vector<int>> &A)
{
if (A.size() != A[0].size()){
cout << "Determinant Error: non-square matrix. n";
return 0;
}
if (A.size() == 2)
{
return A[0][0] * A[1][1] - A[0][1] * A[1][0];
}
else
{
int determinant = 0;
int sign = -1;
for (int i = 0; i < A.size(); i++){
vector<vector<int>> submatrix = extractNext(A, 0, i);
sign = -sign;
int cofactor = sign * A[0][i];
for (int j = 0; j < submatrix.size(); j++){
submatrix[0][j] = cofactor * submatrix[0][j];
}
determinant += det(submatrix);
}
return determinant;
}
}
您的代码没有返回行列式,因为您没有为其创建返回路径。 你也确实依赖副作用。
对于 2*2 矩阵,您的代码应该返回正确的值,前提是您只调用它一次,但这只是因为它立即采用"if"部分,并在一步中完成最终计算。 但是,对于 3*3 矩阵,采用"其他"部分。 但请注意,该路径上没有返回,因此您可以期望您的函数返回垃圾。
要修复它,您需要重写 else 分支,以便计算递归调用返回的值的总和,并为此在堆栈上使用临时变量。 最后,应返回此值。