/*******************************************根據用戶輸入的數據申請一維動態數組,並進行相關的運算,矩陣求和、矩陣相乘、矩陣的逆矩陣、矩陣的伴隨矩陣、矩陣行列式的值(建議採用visual c++6.0編譯).作者:何晏波2013,6,17*********************************************/#include<iostream>#include<cmath>using namespace std;#include"function.h"int main(){ int n,m,n1,m1,count(1); int *p,*p1,i; system("color 1e"); cout<<"請輸入第1個矩陣的行數與列數:"<<endl; cin>>m>>n;//主函數輸入矩陣1 p=new int [m*n]; for(i=0;i<m*n;i++) { if(i%n==0) cout<<"請輸入第"<<i/n+count<<"行的"<<n<<"個元素"<<endl; cin>>p[i]; } cout<<"請輸入第2個矩陣的行數與列數:"<<endl; cin>>m1>>n1;//主函數輸入矩陣2 p1=new int [m1*n1]; for(i=0;i<m1*n1;i++) { if(i%n1==0) cout<<"請輸入第"<<i/n1+count<<"行的"<<n1<<"個元素"<<endl; cin>>p1[i]; } cout<<"============"<<endl; cout<<"你輸入的矩陣1是:"<<endl;print(p,m,n); cout<<"你輸入的矩陣2是:"<<endl; //輸出矩陣1print(p1,m1,n1); //輸出矩陣2if(m==n||m1==n1)cout<<"============\n\n";if(m==n)zhuan_zhi(p,m); //矩陣1的轉置矩陣if(m1==n1)zhuan_zhi(p1,m1); //矩陣2的轉置矩陣if(m==n||m1==n1)cout<<"============\n\n";if(m==m1&&n==n1){count_sum(p,p1,m,n);cout<<"===============\n";}if(n==m1){cheng_matrix(p,p1,m,n,n1);cout<<"====================\n";}if(m==n){cout<<"矩陣1的行列式的值為:"<<determinant(p,m)<<endl;cout<<"=======================\n";}if(m1==n1){cout<<"矩陣2的行列式的值為:"<<determinant(p1,m1)<<endl;cout<<"=======================\n";}if(m==n){cout<<"矩陣1的伴隨矩陣為:\n";companion_matrix(p,m);cout<<"====================\n";}if(m1==n1){cout<<"矩陣2的伴隨矩陣為:\n";cout.unsetf(ios::fixed);cout.precision(6);companion_matrix(p1,m1);cout<<"====================\n";}system("pause"); return 0;}/***********************************function.h頭文件主要實現實現主函數當中的功能模塊,有輸出函數、矩陣求和、求矩陣的逆矩陣、矩陣的伴隨矩陣、矩陣的行列式的值.************************************//******輸出用戶輸入的矩陣******/void print(int p[],int m,int n){ for(int i=0;i<m;i++) { for(int j=0;j<n;j++) cout<<'|'<<p[i*n+j]; cout<<'|'<<endl;}}/******基於一維數組的轉置矩陣******/void zhuan_zhi(int p[],int m){ static int j1=1; int *p1; p1=new int[m*m]; for(int i=0;i<m;i++) for(int j=0;j<m;j++) { p1[j*m+i]=p[i*m+j]; } if(j1<3) cout<<"矩陣"<<j1<<"的轉置矩陣為:"<<endl; print(p1,m,m); j1++;}/******求矩陣的乘法******/void cheng_matrix(int p[],int p1[],int m,int n,int n1){ int *p2=new int[m*n1]; for(int i=0;i<m;i++) { for(int j=0;j<n1;j++) { p2[i*n1+j]=0; for(int k=0;k<n;k++) p2[i*n1+j]+=p[i*n+k]*p1[k*n1+j]; } } cout<<"這兩個矩陣的乘積為:"<<endl; print(p2,m,n1);}/******計算兩個矩陣的和******/void count_sum(int p[],int p1[],int m,int n){ int *p2; p2=new int[n*m]; for(int i=0;i<n*m;i++) p2[i]=p[i]+p1[i]; cout<<"這兩個矩陣的和為:"<<endl; print(p2,m,n);}/******確定行列式中每個元素的符號******/int symble(int n){ if(n%2==0) return 1; return -1;}/******計算矩陣的行列式的值******/int determinant(const int p[],int m) //將參數p定義為只讀參數是防止通過間接尋址方式對它進行改變{ int *temp,*temp1,*temp2,*b,count(0); if(m==1) return p[0]; if(m==2) return (p[0]*p[3]-p[1]*p[2]); if(m==3) return (p[0]*p[4]*p[8]+p[1]*p[5]*p[6]+p[2]*p[3]*p[7]-p[2]*p[4]*p[6]-p[1]*p[3]*p[8]-p[0]*p[7]*p[5]); if(m>3) { temp=new int[m*m]; temp1=new int[(m-1)*(m-1)]; temp2=new int[m*m]; b=new int[m]; for(int g=0;g<m;g++) b[g]=p[g*m]*symble(g); //將每行元素和符號的乘積記錄在數組b中 for(int i=0;i<m;i++) for(int t=0;t<m;t++) //拷貝一個原數組 temp2[i*m+t]=p[i*m+t]; for(int i1=0;i1<m;i1++) for(int t1=0;t1<m-1;t1++) temp2[i1*m+t1]=temp2[i1*m+t1+1]; //將第一列覆蓋掉 for(int y=0;y<m*m;y++) temp[y]=temp2[y]; //將副本中的元素存於一個臨時數組中 for(int j=0;j<m;j++) { for(int l=j;l<m-1;l++) for(int k=0;k<m;k++) temp2[l*m+k]=temp2[(l+1)*m+k]; //將第l行覆蓋掉 /******這步很重要******/ for(int r=0;r<m-1;r++) //這步很重要,一維與二維的區別就在此處,主要的作用是將經過移位後的元素,集中 for(int q=0;q<m-1;q++) //連續放在一維數組中,如果採用二維數組此處可省,當然一維數組在動態方面更具優勢 temp1[r*(m-1)+q]=temp2[r*m+q]; /******important******/ count+=determinant(temp1,m-1)*b[j]; //此處輸出會遇到困難,不像二維數組可以格式輸出,這是一維數組的缺點 for(y=0;y<m*m;y++) temp2[y]=temp[y]; //此處將副本中的元素初始化 } return count; } }/******計算矩陣的伴隨矩陣及其逆矩陣******/void companion_matrix(const int p[],int m) //將參數p定義為只讀參數是防止通過間接尋址方式對它進行改變{ int *temp,*temp1,*temp2; double *t; static int w=1; t=new double[m*m]; temp=new int[m*m]; temp1=new int [m*m]; temp2=new int[m*m]; for(int q=0;q<m;q++) //創建一個最開始的副本,後面用來初始化 for(int q1=0;q1<m;q1++) temp1[q*m+q1]=p[q*m+q1]; for(q=0;q<m;q++) for(int q1=0;q1<m;q1++) //拷貝一個原數組 temp[q*m+q1]=p[q*m+q1]; for(int i=0;i<m;i++) { for(int j=i;j<m;j++) //將原數組元素第i列覆蓋 for(int k=0;k<m-1;k++) temp[j*m+k]=temp[j*m+k+1]; for(j=0;j<m;j++) //創建一個副本後面要用 for(int k=0;k<m;k++) temp2[j*m+k]=temp[j*m+k]; for(int t1=0;t1<m;t1++) { for(int r=t1;r<m-1;r++) for(int r1=0;r1<m;r1++) temp[r*m+r1]=temp[(r+1)*m+r1]; // 將原數組的i行覆蓋 t[t1*m+i]=determinant(temp,m-1)*symble(i+r); //根據伴隨矩陣定義此處一定要轉置 //t數組中存的是伴隨矩陣 for(j=0;j<m;j++) for(int k=0;k<m;k++) temp[j*m+k]=temp2[j*m+k]; //做行變換之前初始化 } for(j=0;j<m;j++) for(int k=0;k<m;k++) temp[j*m+k]=temp1[j*m+k]; //做列變換之前初始化 } for(q=0;q<m;q++) { //輸出伴隨矩陣 for(int q1=0;q1<m;q1++) cout<<'|'<<t[q*m+q1]; cout<<'|'<<endl; } for(q=0;q<m;q++) for(int q1=0;q1<m;q1++) t[q*m+q1]/=fabs(determinant(p,m)); cout.precision(2); cout.setf(ios::fixed); //保留兩位小數控制精度 if(determinant(p,m)!=0) { cout<<"矩陣"<<w<<"的逆矩陣為"<<endl; for(int q2=0;q2<m;q2++) { for(int q3=0;q3<m;q3++) cout<<'|'<<t[q2*m+q3]; //輸出逆矩陣 cout<<'|'<<endl; } w++; } }