老师要求用带行逻辑信息的三元组,加减乘,转制还好说,拿三元组搞还行,可求逆就不行了,没办法,搞了两种求逆的方法。一种是通过求伴随矩阵来搞另一种就是通过与单位矩阵结合,基本变换来求。不说了,把这几天的劳动成果附上。
/***********************建了个matrix.h头文件*************************/
#ifndef MATRIX_H_INCLUDED// 调用时需加stdio.h 和stdlib.h
#define MATRIX_H_INCLUDED
const int maxn = 1e3+100;
typedef double datatype ;
typedef struct node
{
int i, j;
datatype val;
} node;
typedef struct spmartix
{
node data[maxn];
int H[maxn]; //第i行起始位置
int mu, nu, tu; //稀疏矩阵行和列
} spmatrix;
typedef struct matrix
{
datatype S[maxn][maxn];
int row , col;
}matrix;
matrix *minit()
{
matrix *M = ( matrix *) malloc ( sizeof(matrix));
memset( M->S, 0, sizeof(M->S) );
M->row=0;
M->col=0;
return M;
}
spmatrix *init()
{
spmatrix *A = ( spmatrix * )malloc( sizeof ( spmatrix ) );
memset(A->H,-1,sizeof(A->H));
A->mu = 0;
A->nu = 0;
A->tu = 0;
return A;
}
void create( spmatrix *A )
{
printf( "是否文件输入 ? y:文件输入 n:手动输入 ");
char ans[20];
scanf("%s",ans);
if( ans[0] == 'y' || ans[0] == 'Y' )
{
FILE *fp;
printf("请输入文件名: ");
char file_name[100];
scanf( "%s", file_name );
fp = fopen( file_name, "r" );
if( !fp )
{
printf( " 打开文件失败\n" );
return ;
}
else
{
int num = 0;
fscanf( fp,"%d%d", &A->mu,&A->nu);
while( !feof(fp) )
{
fscanf(fp,"%d%d%lf", &A->data[num].i, &A->data[num].j, &A->data[num].val);
if( num == 0 || A->data[num].i != A->data[num-1].i )
{
A->H[A->data[num].i] = num;
}
num++;
}
A->tu = num;
}
fclose( fp );
return ;
}
else
{
printf( "请输入行和列: " );
scanf( "%d%d" , &A->mu, &A->nu );
printf("请输入非零元素的个数: ");
scanf( "%d" , &A->tu);
int num = 0;
int i, j;
int last=0,b;
for( i = 0; i < A->tu ;i++)
{
scanf( "%d%d%lf", &A->data[i].i, &A->data[i].j, &A->data[i].val );
if( i == 0 || A->data[i].i != A->data[i-1].i )
{
A->H[A->data[i].i] = i;
}
}
}
}
void print( spmatrix *A )
{
int i,j,k;
int num = 0 ;
if( A->mu == 0 && A->nu == 0)
{
printf(" 处理失败\n");
return ;
}
for( i = 1; i <=A->mu ; i++ )
{
for( j = 1 ; j <= A->nu ; j++)
{
if( j != 1) printf(" ");
if( num != A->tu && i == A->data[num].i && j == A->data[num].j)
{
printf( "%5.0lf", A->data[num].val);
num++;
}
else putchar( '0' );
}
printf("\n");
}
}
void display(matrix *A)
{
for( int i = 1; i <= A->row ; i++ )
{
for(int j = 1; j <= A->col ; j++)
{
if( j != 1)
{
printf(" ");
}
printf("%5.2lf",A->S[i][j]);
}
printf("\n");
}
}
spmatrix *union_1( spmatrix *A ,spmatrix *B, int c )
{
if( A->mu != B->mu || A->nu != B->nu )
{
printf( "处理失败\n" );
return NULL;
}
spmatrix *C=init();
int num = 0;
int a, b;
int i, j;
a = 0;
b = 0;
while( a < A->tu && b < B->tu )
{
if( A->data[a].i == B->data[b].i && A->data[a].j == B->data[b].j )
{
if( A->data[a].val + B->data[b].val *c != 0 )
{
C->data[num].i = A->data[a].i;
C->data[num].j = A->data[a].j;
C->data[num++].val = A->data[a].val + B->data[b].val * c;
}
a++;
b++;
}
else if( A->data[a].i == B->data[b].i )
{
if( A -> data[a].j < B->data[b].j )
{
C->data[num].i = A->data[a].i;
C->data[num].j = A->data[a].j;
C->data[num++].val = A->data[a].val;
a++;
}
else
{
C->data[num].i = B->data[b].i;
C->data[num].j = B->data[b].j ;
C->data[num++].val = B->data[b].val * c;
b++;
}
}
else if( A->data[a].i < B->data[b].i )
{
C->data[num].i = A->data[a].i;
C->data[num].j = A->data[a].j;
C->data[num++].val = A->data[a].val;
a++;
}
else if( A->data[a].i > B->data[b].i )
{
C->data[num].i = B->data[b].i;
C->data[num].j = B->data[b].j;
C->data[num++].val = B->data[b].val *c ;
b++;
}
}
while( a < A->tu )
{
C->data[num].i = A->data[a].i;
C->data[num].j = A->data[a].j;
C->data[num++].val = A->data[a].val;
a++;
}
while( b < B->tu )
{
C->data[num].i = B->data[b].i;
C->data[num].j = B->data[b].j;
C->data[num++].val = B->data[b].val *c ;
b++;
}
C->mu = A->mu ;
C->nu = A->nu ;
C->tu = num ;
return C;
}
spmatrix *add( spmatrix *A, spmatrix *B )
{
return union_1( A, B, 1 );
}
spmatrix *sub( spmatrix *A, spmatrix *B )
{
return union_1( A, B, -1 );
}
spmatrix *zhuanzhi(spmatrix *A)
{
spmatrix *B=init();
int i,j;
int num=0;
for(i=1;i<=A->nu;i++)
{
for(j=1;j<=A->mu;j++)
{
if(A->H[j]!=-1&&A->data[A->H[j]].j==i)
{
int a=A->H[j];
B->data[num].i=i;
B->data[num].j=j;
B->data[num].val=A->data[a].val;
if(B->H[i]==-1)
B->H[i]=num;
num++;
if(A->data[a+1].i==j)
A->H[j]++;
else A->H[j]=-1;
}
}
}
B->tu=num;
B->mu=A->nu;
B->nu=A->mu;
return B;
}
spmatrix *mult(spmatrix *M,spmatrix *N)
{
spmatrix *Q=init();
Q->mu = M->mu;
Q->nu = N->nu;
spmatrix *B=zhuanzhi(N);
free(N);
N=B;
if(M->nu!=B->nu)
{
printf("当前矩阵不能相乘\n");
return NULL;
}
int i,j,num=0;
for(i=1;i<=M->mu;i++)
{
int a=M->H[i];
if(a==-1)
continue;
int last=1;
int b=a;
datatype sum=0;
for(j=0;j<B->tu;j++)
{
if(b!=-1&&last==B->data[j].i)
{
while(b<M->tu&&M->data[b].i==i&&M->data[b].j<B->data[j].j)
b++;
if(b>M->tu||M->data[b].i>i)
b=-1;
if(b!=-1&&M->data[b].j==B->data[j].j)
sum+=M->data[b].val*B->data[j].val;
}
else
{
if(sum!=0)
{
Q->data[num].i=i;
Q->data[num].j=last;
Q->data[num].val=sum;
num++;
}
last=B->data[j].i;
b=a;
sum=0;
j--;
}
}
if(sum!=0)
{
Q->data[num].i=i;
Q->data[num].j=last;
Q->data[num].val=sum;
num++;
}
}
Q->tu=num;
free(B);
return Q;
}
matrix *transport( spmartix *A)
{
matrix *B=minit();
B->row = A->mu;
B->col = A->nu;
for( int i = 0 ; i < A-> tu ; i++ )
B->S[A->data[i].i][A->data[i].j]=A->data[i].val;
return B;
}
matrix *yuzi(int p,int q,matrix *A)
{
int c, d,i,j;
matrix *B=minit();
for(c=1;c<A->row;c++)
{
for(d=1;d<A->col;d++)
{
if(c<p&&d<q)
{B->S[c][d]=A->S[c][d];}
else if(c<p&&d>=q)
{B->S[c][d]=A->S[c][d+1];}
else if(c>=p&&d<q)
{B->S[c][d]=A->S[c+1][d];}
else
{B->S[c][d]=A->S[c+1][d+1];}
}
}
B->row=A->row-1;
B->col=A->col-1;
return B;
}//求第p行,第q列所在元素的余子式
datatype zhi( matrix *A)
{
int i,j,k;
datatype ans=1.0;
for( i = 1;i <= A->row; i++)
{
if(A->S[i][i]==0)
{
for(j=i+1;j<=A->row;i++)
{
if(A->S[j][i])
break;
}
if( j > A->row)
return 0;
for(k=i;k<=A->col;k++)
{
int t=A->S[i][k];
A->S[i][k]=A->S[j][k];
A->S[j][k]=t;
}
if( j-i%2==1)
ans*=-1;
}
for(j=i+1;j<=A->row;j++)
{
if(A->S[j][i]==0)
continue;
for(k=A->col;k>=i;k--)
{
A->S[j][k]-=A->S[j][i]/A->S[i][i]*A->S[i][k];
}
}
ans*=A->S[i][i];
}
return ans;
}//行列式的值
datatype mo(matrix *A)
{
if(A->row!=A->col)
{
printf("该行列式无法求值\n");
exit(0);
}
else
return (zhi(A));
}//矩阵的模
matrix *bansui(matrix *A)
{
int p, q, x;
matrix *B=minit();
for(p=1;p<=A->row;p++)
{
for(q=1;q<=A->col;q++)
{
if((p+q)%2==0) x=1;
else x=-1;
B->S[p][q]=x*mo(yuzi(q,p,A));
}
}
B->row=A->row;
B->col=A->col;
return B;
}//求伴随矩阵
matrix *ni(matrix *A)
{
int p, q;
matrix *B=minit();
matrix *C=minit();
datatype a;
a=mo(A);
if(a==0)
{printf("该矩阵的模为零,没有逆矩阵\n");exit(0);}
else
{
B=bansui(A);
for(p=1;p<=B->row;p++)
{
for(q=1;q<=B->col;q++)
{
C->S[p][q]=B->S[p][q]/a;
}
}
C->row=B->row;
C->col=B->col;
}
return C;
}
*/
//求逆矩阵
/*
spmatrix *zhuanzhi(spmatrix *A)
{
spmatrix *B=init();
int i,j;
int num=0;
for(i=1;i<=A->nu;i++)
{
for(j=1;j<=A->mu;j++)
{
if(A->H[j]!=-1&&A->data[A->H[j]].j==i)
{
int a=A->H[j];
B->data[num].i=i;
B->data[num].j=j;
B->data[num].val=A->data[a].val;
if(B->H[i]==-1)
B->H[i]=num;
num++;
if(A->data[a+1].i==j)
A->H[j]++;
else A->H[j]=-1;
}
}
}
B->tu=num;
B->mu=A->nu;
B->nu=A->mu;
return B;
}*/
matrix *inversion( spmatrix *A)
{
matrix *C = minit();
int i,j,k;
C->row = A->mu;
C->col = A->nu * 2;
for( i = 0 ; i < A->tu; i++ )
{
C->S[A->data[i].i][A->data[i].j] = A->data[i].val;
}
for( i = 1; i <= A->mu; i++ )
{
C->S[i][A->nu+i] = 1;
}
for( i = 1; i <= A->mu; i++ )
{
if(C->S[i][i] == 0 )
{
for( j=i+1; j<= A->mu ; j++ )
{
if( C->S[j][i] != 0 )
{
break;
}
}
if( j > A->mu )
{
printf(" 无逆\n");
return NULL;
}
for( k = 0; k <= C->col ; k++ )
{
int t;
t = C->S[i][k];
C->S[i][k] = C->S[j][k];
C->S[j][k] = t;
}
}
for( j = C->col; j >=i; j-- )
{
C->S[i][j] /= C->S[i][i];
}
for( j = 1; j <= C->row;j++)
{
if( j == i )
continue;
if( C->S[j][i] != 0)
{
for( k = C->col; k >= i; k-- )
{
C->S[j][k] = C->S[j][k] - C->S[i][k]*C->S[j][i];
}
}
}
}
for( i = 1; i <= C->row; i++ )
{
for( j = 1; j <= C->row ; j++ )
{
C->S[i][j] = C->S[i][j+C->row];
}
}
C->col /= 2;
return C;
}
#endif // MATRIX_H_INCLUDED
//主函数
<pre name="code" class="cpp">#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "matrix.h"
int menu_start(int a)
{
int i,j;
if( a == 0 )
printf( "\n\t\t\t\t\t\t 欢迎使用矩阵计算器\n\n" );
printf("*");
for( i = 0; i < 117; i++ )
printf("-");
printf("*\n");
printf("|\t\t\t\t\t\t\t功能\t\t\t\t\t\t\t\t |\n");
for( j = 0 ; j < 2 ; j++ )
{
printf("|");
for( i = 0; i < 117; i++ )
printf(" ");
printf("|\n");
}
printf("|\t\t\t\t\t操作 #1: -----------------矩阵加法\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #2: -----------------矩阵减法\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #3: -----------------矩阵乘法\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #4: -----------------矩阵求逆\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #5: -----------------矩阵转置\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #6: -----------------行列式值\t\t\t\t |\n");
printf("|\t\t\t\t\t操作 #7: -----------------退出\t\t\t\t\t |\n");
printf("|");
for( i = 0; i < 117; i++ )
printf(" ");
printf("|\n");
printf("*");
for( i = 0; i < 117; i++ )
printf("-");
printf("*\n\n\n\n\n");
printf("\t\t\t\t\t请输入所需操作序号 : ");
int b;
scanf( "%d" ,&b);
return b;
}
int main()
{
int a;
a = menu_start(0);
while( a != 7 )
{
system( "CLS" );
printf( " 请输入一个矩阵 \n");
spmatrix *A = init() ;
create ( A );
system( "CLS" );
switch ( a )
{
case 1 :
{
printf(" 请输入另一个矩阵 \n");
spmatrix *B= init();
create ( B );
system( "CLS" );
spmatrix *C = add( A, B);
free(B);
if(!C)
break;
printf("两矩阵和为\n");
print ( C );
free ( C );
break;
}
case 2 :
{
printf(" 请输入另一个矩阵 \n");
spmatrix *B= init();
create ( B );
system("PAUSE");
system( "CLS" );
spmatrix *C = sub( A, B);
free(B);
if(!C)
break;
printf(" 两矩阵差为\n" );
print ( C );
free(C);
break;
}
case 3 :
{
printf(" 请输入另一个矩阵 \n");
spmatrix *B= init();
create ( B );
system( "CLS" );
spmatrix *C = mult( A, B);
if(!C)
break;
printf(" 两矩阵相乘为\n" );
print ( C );
free(C);
break;
}
case 4 :
{
matrix *B= transport(A);
if(!B)
break;
matrix *C = ni(B);
if(!C)
break;
printf(" 该矩阵求逆为\n" );
printf("FIRST :\n");
display(C);
free(C);
C=inversion(A);
if(!C)
break;
printf("SECOND :\n");
display(C);
free(B);
free(C);
break;
}
case 5 :
{
spmatrix *C=zhuanzhi(A);
if(!C)
break;
printf(" 该矩阵转置为\n" );
print(C);
free(C);
break;
}
case 6 :
{
matrix *B= transport(A);
if(!B)
{
break;
}
int b=0;
datatype ans=mo(B,b);
if(b==0)
printf(" 该矩阵行列式值为: %8.2lf\n",ans );
free(B);
break;
}
}
free(A);
system( "PAUSE") ;
system( "CLS" );
a = menu_start ( 1 );
}
system( "CLS" );
printf("\n\n\n\n\t\t\t\t\t\tBYE-BYE\n\n\n\n\n");
return 0;
}