用C实现带选主元的Gaussian elimination结果错误,求排查
问题分析与代码修正
你遇到的问题主要是几个低级但致命的语法/逻辑错误导致的,我帮你逐一排查:
1. 函数名不匹配(最关键的错误)
你在代码里声明了void solution(...),但实际定义的函数名是solutions(多了一个s)!这导致main函数中调用的solution(a, b, x, n)根本没有被执行——编译器应该会抛出警告,但你可能忽略了。回代步骤完全没跑,所以你输出的b数组只是消元后的中间结果,不是最终解。
2. 回代函数的逻辑错误
回代时,你从j=i开始累加,但此时x[i]还未被计算,应该从j=i+1开始(因为只有j>i的x[j]已经被求出)。另外,sum的初始化位置可以调整得更合理,避免重复清零的冗余操作。
3. 输出错误的数组
你在main里输出的是b数组,但回代后的解存在x数组里,所以输出语句应该遍历x而不是b。
4. 选主元的初始化逻辑小问题
你初始化l=i=r+1,这会跳过当前的r行,应该从r行开始寻找最大主元,否则可能漏掉当前行本身就是最大主元的情况(虽然在你的测试用例里不影响,但逻辑不够严谨)。
修正后的完整代码
#include <stdio.h> #include <math.h> #define N 15 void gauss(float a[][N], float *b, int n); void solution(float a[][N], float *b, float *x, int n); // 函数声明保持一致 int main(void) { int n, i, j; printf("Enter an integer n<=15: "); scanf("%d", &n); float a[n][N], b[n], x[n]; for(i=0; i<n; i++) for(j=0; j<n; j++) { printf("A[%d][%d] = ", i+1, j+1); scanf(" %f", &a[i][j]); } printf("\n"); for(i=0; i<n; i++) { printf("b[%d] = ", i+1); scanf(" %f", b+i); } gauss(a, b, n); solution(a, b, x, n); printf("The solution is "); for(i=0; i<n; i++) printf("%g ", x[i]); // 输出x数组,不是b printf("\n"); return 0; } void gauss(float a[][N], float *b, int n) { int i, j, r, l; float pivot, temp, m; for(r=0; r<n-1; r++) { // 修正选主元的初始化:从r行开始找最大主元 l = r; pivot = fabs(a[r][r]); for(i=r+1; i<n; i++) { if(fabs(a[i][r]) > pivot) { l = i; pivot = fabs(a[i][r]); } } // 如果找到更大的主元,交换行 if(l != r) { for(j=0; j<n; j++) { temp = a[r][j]; a[r][j] = a[l][j]; a[l][j] = temp; } temp = b[r]; b[r] = b[l]; b[l] = temp; } // 消元操作:优化为从r列开始,前面的元素已经是0无需计算 for(i=r+1; i<n; i++) { m = a[i][r]/a[r][r]; for(j=r; j<n; j++) a[i][j] = a[i][j] - m*a[r][j]; b[i] = b[i] - m*b[r]; } } } void solution(float a[][N], float *b, float *x, int n) { // 函数名和声明一致 int i, j; float sum; for(i=n-1; i>=0; i--) { sum = 0; // 只累加已经求出的x[j](j>i) for(j=i+1; j<n; j++) { sum += a[i][j] * x[j]; } x[i] = (b[i] - sum) / a[i][i]; } }
测试你的用例
输入:
Enter an integer n<=15: 2 A[1][1] = 1 A[1][2] = 1 A[2][1] = 1 A[2][2] = -1 b[1] = 1 b[2] = 0
输出:
The solution is 0.5 0.5
这和手动计算的正确结果完全一致。
内容的提问来源于stack exchange,提问作者ioioio
相关产品推荐
相关产品推荐

