《数值分析》课的作业。查看了网上的别人编的程序,一般都先定义了矩阵的行数和列数。
我这个程序使用了二维动态数组,可以在运行过程中输入行数列数。
//codey by Chen Zhen, 2014/10/17, Beihang University //使用了二维动态数组 #include<iostream> #include<math.h> #include<iomanip> using namespace std; void Gauss(double **a, double *b,int);//顺序Gauss消去法 void lie_Gauss(double **a, double *b,int);//列主元素Gauss消去法 void Doolittle(double **a, double *b,int);//Doolittle分解法 void print( double **a, double *b,int);//打印方程 void main() { //cout.setf(ios::fixed); cout.precision(4);//设置四位有效数字 //输入矩阵A和b int n; cout<<"请输入系数矩阵的行数(或列数,列数等于行数):\n"; cin>>n; cin.clear();//这3行代码重置输入 while(cin.get()!='\n') continue; cout<<"请输入系数矩阵A:\n"; //要用到二维动态数组 double **a; a=new double *[n]; //申请行的空间 for (int i=0;i<n;i++) a[i]=new double[n]; for (int i=0;i<n;i++) { cout<<"第 "<< i+1<<" 行:"; for (int j=0;j<n;j++) while(!(cin>>a[i][j])) { cin.clear(); while(cin.get()!='\n') continue; cout<<"请输入数字"; } cin.clear(); while(cin.get()!='\n') continue; } cout<<"请输入矩阵b:\n"; double *b=new double[n]; for (int j=0;j<n;j++) cin>>b[j]; cin.clear(); while(cin.get()!='\n') continue; //将系数矩阵A与矩阵b存储在临时矩阵中,临时矩阵中的元素参与行列变换 double **temp_a=new double *[n]; double *temp_b=new double[n]; for (int i=0;i<n;i++) temp_a[i]=new double[n]; for (int i=0;i<n;i++) for (int j=0;j<n;j++) temp_a[i][j]=a[i][j]; for (int i=0;i<n;i++) temp_b[i]=b[i]; //打印方程 print(( double **)temp_a,temp_b,n); //选择解方程方式 cout<<"请输入你选择的解方程方式(数字):\n"; cout<<"*************************\n"; cout<<"1.顺序Gauss法\n2.列主元素高斯法\n"; cout<<"3.Doolittle分解法\n"; cout<<"*************************\n"; int choice; while(cin>>choice) { switch (choice) { case 1: Gauss(( double **)temp_a,temp_b,n); break; case 2: lie_Gauss(( double **)temp_a,temp_b,n); break; case 3: Doolittle(( double **)temp_a,temp_b,n); break; case 0: return; } cout<<"请输入你选择的解方程方式(1-3的数),输入0退出:\n"; } for (int i=0;i<n;i++) delete []temp_a[i]; delete []temp_a; delete []temp_b; for (int i=0;i<n;i++) delete []a[i]; delete []a; delete []b; } void Gauss( double **a,double *b,int n) { double mm; double *jie=new double[n]; for (int k=1;k<n;k++) { if (a[k-1][k-1]==0) { cout<<"算法失效"<<endl; return; } for (int i=k+1;i<n+1;i++) { mm=a[i-1][k-1]/a[k-1][k-1]; for (int j=k+1;j<n+1;j++) { a[i-1][j-1]=a[i-1][j-1]-mm*a[k-1][j-1]; } b[i-1]=b[i-1]-mm*b[k-1]; for (int j=1;j<k+1;j++) a[i-1][j-1]=0; } //print((double**)a,b,n); } if (a[n-1][n-1]==0) { cout<<"算法失效"<<endl; return; } cout<<"使用顺序Gauss消去法的解为:\n"; jie[n-1]=b[n-1]/a[n-1][n-1]; for (int k=n-1;k>0;k--) { double temp=0; for (int j=k+1;j<n+1;j++) temp+=a[k-1][j-1]*jie[j-1]; jie[k-1]=(b[k-1]-temp)/a[k-1][k-1]; } for (int i=0;i<n-1;i++) cout<<"x"<<i+1<<" = "<<jie[i]<<endl; cout<<"x"<<n<<" = "<<jie[n-1]<<endl; cout<<endl; delete []jie; } void lie_Gauss( double **a,double *b,int n) { for (int k=1;k<n;k++) { double max=abs(a[k-1][k-1]); int lie_hao=k; for (int i=k;i<n+1;i++) if (abs(a[i-1][k-1])>max) { max=abs(a[i-1][k-1]); lie_hao=i; } for (int j=k;j<n+1;j++) { double temp=a[k-1][j-1]; a[k-1][j-1]=a[lie_hao-1][j-1]; a[lie_hao-1][j-1]=temp; } for (int i=k+1;i<n+1;i++) { double mm=a[i-1][k-1]/a[k-1][k-1]; for (int j=k+1;j<n+1;j++) { a[i-1][j-1]=a[i-1][j-1]-mm*a[k-1][j-1]; } b[i-1]=b[i-1]-mm*b[k-1]; for (int j=1;j<k+1;j++) a[i-1][j-1]=0; } } cout<<"使用列主元素Gauss法的解为:\n"; double *jie=new double[n]; jie[n-1]=b[n-1]/a[n-1][n-1]; for (int k=n-1;k>0;k--) { double temp=0; for (int j=k+1;j<n+1;j++) temp+=a[k-1][j-1]*jie[j-1]; jie[k-1]=(b[k-1]-temp)/a[k-1][k-1]; } for (int i=0;i<n-1;i++) cout<<"x"<<i+1<<" = "<<jie[i]<<endl; cout<<"x"<<n<<" = "<<jie[n-1]<<endl; cout<<endl; delete []jie; } void Doolittle(double **a,double *b,int n) { double **u=new double *[n]; for (int i=0;i<n;i++) u[i]=new double[n]; double **l=new double *[n]; for (int i=0;i<n;i++) l[i]=new double[n]; double *jie_x=new double[n]; double *jie_y=new double[n]; for (int k=1;k<n+1;k++) { for (int j=k,i=k+1;j<n+1,i<n+1;j++,i++) { double sum_1=0; for (int t=1;t<k;t++) { sum_1+=l[k-1][t-1]*u[t-1][j-1]; } u[k-1][j-1]=a[k-1][j-1]-sum_1; double sum_2=0; for (int t=1;t<k;t++) { sum_2+=l[i-1][t-1]*u[t-1][k-1]; } l[i-1][k-1]=(a[i-1][k-1]-sum_2)/u[k-1][k-1]; } double sum_1=0; for (int t=1;t<k;t++) { sum_1+=l[k-1][t-1]*u[t-1][n-1]; } u[k-1][n-1]=a[k-1][n-1]-sum_1; } jie_y[0]=b[0]; for (int i=2;i<n+1;i++) { double sum=0; for (int t=1;t<i;t++) sum+=l[i-1][t-1]*jie_y[t-1]; jie_y[i-1]=b[i-1]-sum; } jie_x[n-1]=jie_y[n-1]/u[n-1][n-1]; for(int i=n-1;i>0;i--) { double sum=0; for (int t=i+1;t<n+1;t++) sum+=u[i-1][t-1]*jie_x[t-1]; jie_x[i-1]=(jie_y[i-1]-sum)/u[i-1][i-1]; } cout<<"使用Doolittle分解法的解为\n"; for (int i=0;i<n-1;i++) cout<<"x"<<i+1<<" = "<<jie_x[i]<<endl; cout<<"x"<<n<<" = "<<jie_x[n-1]<<endl; cout<<endl; delete []jie_x; delete []jie_y; for (int i=0;i<n;i++) delete []u[i]; delete []u; for (int i=0;i<n;i++) delete []l[i]; delete []l; } void print(double **a,double *b,int n) { cout<<"方程为:\n"; cout<<"====================================================\n"; for (int i=0;i<n;i++) { for (int j=0;j<n-1;j++) { cout<<a[i][j]<<" x"<< j+1<<" + "; } cout<<a[i][n-1]<<" x"<<n<<" = "<<b[i]<<endl; } cout<<"====================================================\n"; cout<<endl; }