尝试使用二维数组
Trying to use 2D arrays
我知道有人问过这个问题,但我还没有真正看到对我有意义的答案。
我正在编写一个用 C++ 计算行列式的函数。为此,我需要传递一个矩阵。
我的代码如下所示:
#include <stdlib.h>
#include <stdio.h>
double determinant(int N, double M[N][N]);
int main(){
double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
double okay = determinant(4, myMatrix);
printf("determinant = %f\n", okay);
}
double determinant(int N, double M[N][N]){
double det=0.0;
//if N=2 matrix, use the easy formula
if(N==2){
det = M[0][0]*M[1][1] - M[0][1]*M[1][0];
}
//otherwise, find minor matrices, multiply by top row
else {
double Mminor[N-1][N-1];
double sign = 1.0;
for(int i=0; i<N; i++){
//get the minor matrix
for(int a=1;a<N;a++){
int m=0;
for(int b=0;b<N;b++){
if(b!=i){
Mminor[a-1][m] = M[a][b];
m++;
}
}
}
//add top row element times determinant of its minor
det += sign*M[0][i]*determinant(N-1, Mminor);
//swap the sign
sign *= -1.0;
}
}
return det;
}
如果我将其编译为 C 并使用 C99 编译器,它运行良好且没有任何问题,为几个不同的测试矩阵提供了正确的值。
但是我不需要它来编译为 C,我需要它来编译为 C++。而且它不会编译为 C++。 GNU 编译器给出以下错误:
determinant.c:25:24: error: no matching function for call to 'determinant'
det += sign*M[0][i]*determinant(N-1, Mminor);
^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [N - 1][N - 1]' to
'double (*)[N]' for 2nd argument
double determinant(int N, double M[N][N]){
^
determinant.c:36:16: error: no matching function for call to 'determinant'
double okay = determinant(4, myMatrix);
^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [4][4]' to 'double (*)[N]'
for 2nd argument
double determinant(int N, double M[N][N]){
我知道 C 和 C++ 对二维数组有很深的偏见并且不喜欢它们并拒绝使用它们,但是我读过的所有内容都表明通过指定大小 N 作为参数它应该管用。确实如此。在 C99 中。但不适用于 g++ 编译器(既不是 C++99 也不是 C++11)。
我必须使用一些特定的编译器标志吗?或者其他一些方法来做到这一点?
明确一点:我需要矩阵的大小是灵活的,因为每次调用函数时它都会不同。
如果可能的话,我想避免使用一维数组来制作二维数组。我知道如何使用一维数组执行此操作,但我宁愿以更自然和优雅的方式执行此操作。
谢谢。
编辑:我知道您会建议我改用 vector<>。使用 vector<> 不是最佳选择,因为这一切都应该进入一个更大的程序,大约 20,000 行,只使用数组。
编辑 2:The GNU compiler documentation 说它在 C++ 中实现 VLA 作为语言的扩展。其他几位过去的发帖人对 VLA 的工作感到惊讶,并询问如何关闭该功能。但是如何开启它呢?
在 C++ 中,您可以使用模板:
#include <iostream>
double determinant(const double (&M)[2][2]){
return M[0][0] * M[1][1] - M[0][1] * M[1][0];
}
template <std::size_t N>
double determinant(const double (&M)[N][N]){
double det=0.0;
double Mminor[N - 1][N - 1];
double sign = 1.0;
for (int i = 0; i < N; i++) {
//get the minor matrix
for (int a = 1; a < N; a++) {
int m=0;
for (int b = 0; b < N; b++) {
if (b != i) {
Mminor[a - 1][m] = M[a][b];
m++;
}
}
}
//add top row element times determinant of its minor
det += sign * M[0][i] * determinant(Mminor);
//swap the sign
sign *= -1.0;
}
return det;
}
int main(){
const double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
double okay = determinant(myMatrix);
std::cout << "determinant = " << okay << std::endl;
}
我知道有人问过这个问题,但我还没有真正看到对我有意义的答案。
我正在编写一个用 C++ 计算行列式的函数。为此,我需要传递一个矩阵。
我的代码如下所示:
#include <stdlib.h>
#include <stdio.h>
double determinant(int N, double M[N][N]);
int main(){
double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
double okay = determinant(4, myMatrix);
printf("determinant = %f\n", okay);
}
double determinant(int N, double M[N][N]){
double det=0.0;
//if N=2 matrix, use the easy formula
if(N==2){
det = M[0][0]*M[1][1] - M[0][1]*M[1][0];
}
//otherwise, find minor matrices, multiply by top row
else {
double Mminor[N-1][N-1];
double sign = 1.0;
for(int i=0; i<N; i++){
//get the minor matrix
for(int a=1;a<N;a++){
int m=0;
for(int b=0;b<N;b++){
if(b!=i){
Mminor[a-1][m] = M[a][b];
m++;
}
}
}
//add top row element times determinant of its minor
det += sign*M[0][i]*determinant(N-1, Mminor);
//swap the sign
sign *= -1.0;
}
}
return det;
}
如果我将其编译为 C 并使用 C99 编译器,它运行良好且没有任何问题,为几个不同的测试矩阵提供了正确的值。
但是我不需要它来编译为 C,我需要它来编译为 C++。而且它不会编译为 C++。 GNU 编译器给出以下错误:
determinant.c:25:24: error: no matching function for call to 'determinant'
det += sign*M[0][i]*determinant(N-1, Mminor);
^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [N - 1][N - 1]' to
'double (*)[N]' for 2nd argument
double determinant(int N, double M[N][N]){
^
determinant.c:36:16: error: no matching function for call to 'determinant'
double okay = determinant(4, myMatrix);
^~~~~~~~~~~
determinant.c:5:8: note: candidate function not viable: no known conversion from 'double [4][4]' to 'double (*)[N]'
for 2nd argument
double determinant(int N, double M[N][N]){
我知道 C 和 C++ 对二维数组有很深的偏见并且不喜欢它们并拒绝使用它们,但是我读过的所有内容都表明通过指定大小 N 作为参数它应该管用。确实如此。在 C99 中。但不适用于 g++ 编译器(既不是 C++99 也不是 C++11)。
我必须使用一些特定的编译器标志吗?或者其他一些方法来做到这一点?
明确一点:我需要矩阵的大小是灵活的,因为每次调用函数时它都会不同。
如果可能的话,我想避免使用一维数组来制作二维数组。我知道如何使用一维数组执行此操作,但我宁愿以更自然和优雅的方式执行此操作。
谢谢。
编辑:我知道您会建议我改用 vector<>。使用 vector<> 不是最佳选择,因为这一切都应该进入一个更大的程序,大约 20,000 行,只使用数组。
编辑 2:The GNU compiler documentation 说它在 C++ 中实现 VLA 作为语言的扩展。其他几位过去的发帖人对 VLA 的工作感到惊讶,并询问如何关闭该功能。但是如何开启它呢?
在 C++ 中,您可以使用模板:
#include <iostream>
double determinant(const double (&M)[2][2]){
return M[0][0] * M[1][1] - M[0][1] * M[1][0];
}
template <std::size_t N>
double determinant(const double (&M)[N][N]){
double det=0.0;
double Mminor[N - 1][N - 1];
double sign = 1.0;
for (int i = 0; i < N; i++) {
//get the minor matrix
for (int a = 1; a < N; a++) {
int m=0;
for (int b = 0; b < N; b++) {
if (b != i) {
Mminor[a - 1][m] = M[a][b];
m++;
}
}
}
//add top row element times determinant of its minor
det += sign * M[0][i] * determinant(Mminor);
//swap the sign
sign *= -1.0;
}
return det;
}
int main(){
const double myMatrix[3][3] = {{1,2,3}, {4,5,6}, {3,6,1}};
double okay = determinant(myMatrix);
std::cout << "determinant = " << okay << std::endl;
}