1. 程式人生 > >資料結構——稀疏矩陣運算器(C語言)

資料結構——稀疏矩陣運算器(C語言)

資料結構——稀疏矩陣運算器(C語言)

/*****************稀疏矩陣運算器 ****************/

#include<stdio.h>
#include<stdlib.h>

#define OK    1
#define TRUE  1
#define ERROR 0
#define FALSE 0

#define MAX_SIZE 100
 

typedef struct{      //構造三元組 
	int x;
	int y; 
	int e;
}Triad;
typedef struct {
	int mrow,mcol,ms;
	Triad data[MAX_SIZE];
}Rtriad;

void Input(Rtriad &S){                                  //以三元組方式輸入矩陣 
	printf("請輸入行,列(row col):");
	scanf("%d%d",&S.mrow,&S.mcol);
	printf("請以行序為主序,以三元組的方式輸入矩陣元素,'-1 -1 -1'表示結束:\n"); 
	int x,y,z;
	scanf("%d%d%d",&x,&y,&z);
	S.ms=0;
	while(!(x==-1&&y==-1&&z==-1)){                 //長度為S.ms+1,從0開始到S.ms 
		S.data[S.ms].x=x;
		S.data[S.ms].y=y;
		S.data[S.ms].e=z; 
		S.ms++;   
		scanf("%d%d%d",&x,&y,&z);
	}
	S.ms--;
}

void Add(Rtriad S1,Rtriad S2,Rtriad &S3){              //矩陣相加 
	if(S1.mcol!=S2.mcol||S1.mrow!=S2.mrow){
		printf("ERROR!!!\n");
		return ;
	}
	S3.mcol=S1.mcol ;
	S3.mrow=S1.mrow ;
	S3.ms=0;
	int row,col,s,x,y,z;
	for(row=1;row<=S3.mrow;row++){
		for(col=1;col<=S3.mcol;col++){
			z=0;
			for(s=0;s<=S1.ms;s++){
				if(S1.data[s].x==row&&S1.data[s].y==col){
					S3.data[S3.ms].x=row;
					S3.data[S3.ms].y=col;
					S3.data[S3.ms].e=S1.data[s].e;
				    z++;    
				}
			}
			for(s=0;s<=S2.ms;s++){
				if(S2.data[s].x==row&&S2.data[s].y==col){
					S3.data[S3.ms].x=row;
					S3.data[S3.ms].y=col;
					if(z==0)
					    S3.data[S3.ms].e=S2.data[s].e;
				    else
					    S3.data[S3.ms].e+=S2.data[s].e;
				    z++;				    
				}	
			}
			if(z!=0)
			    S3.ms++;
		}
	}
	
	int m=0;
	for(int t=0;t<=S3.ms;t++){
		if(S3.data[t].e==0){     //刪除
		for(int i=t+1;i<S3.ms;i++){
			S3.data[i-1]=S3.data[i];
		} 
		m++;
		}
	} 
	S3.ms-=m;
}

void Printf(Rtriad S){                                 //列印矩陣 
	int a[S.mrow][S.mcol];
	for(int i=0;i<S.mrow;i++)
	    for(int j=0;j<S.mcol;j++)
	        a[i][j]=0;
	
	for(int k=0;k<=S.ms;k++)
		a[S.data[k].x-1][S.data[k].y-1]=S.data[k].e;   
		
	//printf("\n\n矩陣為:\n");	
	for(int i=0;i<S.mrow;i++){
	    for(int j=0;j<S.mcol;j++)
	        printf("%-2d ",a[i][j]);
		printf("\n");		  
	}
}

void Sub(Rtriad S1,Rtriad S2,Rtriad &S3){             //矩陣相減   
	for(int i=0;i<=S2.ms;i++)
	    S2.data[i].e*=-1;
	Add(S1,S2,S3);
	for(int i=0;i<=S2.ms;i++)
	    S2.data[i].e*=-1;    
}

void Mult(Rtriad S1,Rtriad S2,Rtriad &S3){           //矩陣相乘
    if(S1.mcol!=S2.mrow){
    	printf("ERROR!!!\n");
    	return ;
	}
	
	S3.mrow=S1.mrow;
	S3.mcol=S2.mcol;
	S3.ms=0;
	
	int s1[S1.mrow][S1.mcol];
	int s2[S2.mrow][S2.mcol];
	int s3[S3.mrow][S3.mcol];
	
	for(int i=0;i<S1.mrow;i++)
	    for(int j=0;j<S1.mcol;j++)
	    	s1[i][j]=0; 	
	for(int i=0;i<S2.mrow;i++)
	    for(int j=0;j<S2.mcol;j++)
	    	s2[i][j]=0;
	for(int i=0;i<S3.mrow;i++)
	    for(int j=0;j<S3.mcol;j++)
	    	s3[i][j]=0;
	    	
	    	
	for(int k=0;k<=S1.ms;k++)
		s1[S1.data[k].x-1][S1.data[k].y-1]=S1.data[k].e;
	for(int k=0;k<=S2.ms;k++)
		s2[S2.data[k].x-1][S2.data[k].y-1]=S2.data[k].e;		
	 
	for(int row=0;row<S3.mrow;row++){
		for(int col=0;col<S3.mcol;col++){
			for(int k=0;k<S1.mcol;k++)
				s3[row][col]+=(s1[row][k]*s2[k][col]);
				
			if(s3[row][col]!=0){
				S3.data[S3.ms].x=row+1;
				S3.data[S3.ms].y=col+1;
				S3.data[S3.ms].e=s3[row][col];
				S3.ms++;
			}	
		}
	}
}

void Tran(Rtriad &S1,Rtriad &S2){                   //矩陣的快速轉置 
	
	S2.ms=S1.ms;
	S2.mcol=S1.mrow;
	S2.mrow=S1.mcol;
	int num[MAX_SIZE];      //每一列的元素個數 ,從1開始計數 
	int pos[MAX_SIZE];      
	
	for(int col=1;col<=S1.mcol;col++)   //初始化num 
	    num[col]=0;
	    
	for(int i=0;i<=S1.ms;i++)    //給num賦值 ,num從1開始 
		num[S1.data[i].y]++;
				
	pos[1]=1;                     //給pos賦值 ,pos從1開始 
	for(int col=2;col<=S1.mcol;col++)
	    pos[col]=pos[col-1]+num[col-1];

	for(int k=0;k<=S1.ms;k++){              //S1,S2都是從data[0]開始的 
		int col=S1.data[k].y;
		int q=pos[col];
		S2.data[q-1].e=S1.data[k].e;
		S2.data[q-1].x=S1.data[k].y;
		S2.data[q-1].y=S1.data[k].x;
		
		pos[col]++;
	}	

}

int main(){
    printf("/*****************稀疏矩陣運算器 ****************/\n\n");
    printf("功能選擇:\n1.矩陣相加\n2.矩陣相減\n3.矩陣相乘\n4.矩陣轉置\n");
    int n;
    printf("選擇功能:"); 
	scanf("%d",&n);
	Rtriad S1,S2,S3;
	switch(n){
		case 1:
			printf("\n請輸入矩陣1:\n");
			Input(S1);
			printf("\n請輸入矩陣2:\n");
			Input(S2);
			Add(S1,S2,S3);
			printf("\n結果為:\n");
			Printf(S3); 
			break;
		case 2:
			printf("\n請輸入矩陣1:\n");
			Input(S1);
			printf("\n請輸入矩陣2:\n");
			Input(S2);
			Sub(S1,S2,S3);
			printf("\n結果為:\n");
			Printf(S3); 
			break;	
		case 3:
			printf("\n請輸入矩陣1:\n");
			Input(S1);
			printf("\n請輸入矩陣2:\n");
			Input(S2);
			Mult(S1,S2,S3);
			printf("\n結果為:\n");
			Printf(S3); 
			break;	
		case 4:
			printf("\n請輸入矩陣1:\n");
			Input(S1);
			Tran(S1,S2);
			printf("\n結果為:\n");
			Printf(S3); 
			break;
	}
	return 0;
}