P.S.我去、、我大作业不会打成系数矩阵了吧!!!!!!!!!!!
一、题目描述:
对于一个Rows X Columns稀疏矩阵,使用三元组的方法进行存储。
并在此基础上计算矩阵的乘法
二、解题报告
1.建立结构_Matrix
1 MAXVALUE为预估零元峰值个数, 2 struct _Matrix 3 { 4 int Sum;//实际输入总非零点数 5 int Rows,Columns;//矩阵行数,列数 6 double Data[MAXVALUE+1];//数据域,第i个数据的值 7 int Row[MAXVALUE+1],Column[MAXVALUE+1]; 8 //第i个数据是第Row[i]行,Column[i]列 9 };
由此,可新建N个矩阵数组
_Matrix Matrix[N+1];
实际存储,需要运算的为Matrix[1]、Matrix[2],答案临时存储于Matrix[0]
2.主程序框架
1 int main() 2 { 3 Init();//初始化Matrix 4 for (int i=1;i<=N;++i) 5 InputData(i);//读入N(#define N 2)个Matrix 6 MultiplyMatrix(1,2); 7 OutputData(); 8 return 0; 9 }
3.初始化过程Init();
1 /*初始化系数矩阵,Data,行、列矩阵指针Row、Column*/ 2 void Init() 3 { 4 for (int j=1;j<=N;++j) 5 for (int i=0;i<=MAXVALUE;++i) 6 Matrix[j].Data[i]=Matrix[j].Row[i]=Matrix[j].Column[i]=0; 7 }
4.读入模块InputData(int i);
1 void InputData(int i) 2 { 3 cout<<"请输入第"<<i<<"个矩阵"<<endl; 4 cout<<"请输入矩阵的行数和列数"<<endl; 5 cin>>Matrix[i].Rows>>Matrix[i].Columns; 6 cout<<"请依次输入矩阵元素,-1为结束标志"<<endl; 7 while (1) 8 { 9 cin>>Matrix[i].Row[++Matrix[i].Sum];//行指标,每一个非零元个数加1 10 if (Matrix[i].Row[Matrix[i].Sum]==-1)//-1为终止标志 11 { 12 --Matrix[i].Sum;//多读了个-1,所以Sum-- 13 break; 14 } 15 cin>>Matrix[i].Column[Matrix[i].Sum];//读入列数指标 16 cin>>Matrix[i].Data[Matrix[i].Sum];//读入系数值 17 } 18 } 19 P.S.关于读入方法的声明 20 cout<<"读入方法如下:"<<endl; cout<<"输入矩阵的行数和列数"<<endl; 21 cout<<"然后依次读入元素"<<endl; cout<<"第i行,第j列的值为Value"<<endl; 22 cout<<"则输入i j Value"<<endl; cout<<"输入-1时结束对本矩阵读入"<<endl; 23 cout<<"如对矩阵12 0 0"<<endl; 24 cout<<" 0 0 1"<<endl; 25 cout<<" 0 0 0"<<endl; 26 cout<<"请输入:3 3 "<<endl; 27 cout<<"请输入:1 1 12"<<endl; cout<<" 2 3 1 "<<endl; 28 cout<<" -1 "<<endl;
5.矩阵乘法模块MultiplyMatrix(_Matrix A,B);
思想:依照矩阵乘法原则,通过O(N^2)查找对比,
将需要进行乘法的对应项相乘,结果存放在Matrix[0]尾三元组
然后将相同项相加,将Matrix[0]排序以便于输出。实际编写时,将本行写在输出中。
即只对最初结果三元组进行行、列从小到大排序,合并工作交由输出解决。
1 void MultiplyMatrix(int N1,int N2) 2 { if (Matrix[N1].Columns != Matrix[N2].Rows) //判断是否可乘 3 { 4 cout<<"矩阵不可乘!请检查输入"<<endl; 5 return ; 6 } 7 Matrix[0].Rows=Matrix[N1].Rows; 8 Matrix[0].Columns=Matrix[N2].Columns; 9 //根据矩阵乘法规则确定所得答案矩阵行列指标 10 n=0;//初始化计数器 11 /*时间复杂度O(N1.Sum*N2.Sum)*/ 12 for (int i=1;i<=Matrix[N1].Sum;++i) 13 for (int j=1;j<=Matrix[N2].Sum;++j) 14 if (Matrix[N1].Column[i]==Matrix[N2].Row[j]) 15 //1矩阵列指标==2矩阵行指标时,相乘 16 { 17 Matrix[0].Data[++n]=Matrix[N1].Data[i]*Matrix[N2].Data[j]; 18 Matrix[0].Row[n]=Matrix[N1].Row[i];//行为1矩阵对应行 19 Matrix[0].Column[n]=Matrix[N2].Column[j];//列为2矩阵对应列 20 } 21 qSort(1,n);//按行指标对答案矩阵三元组进行QuickSort 22 /* ///试图对行指标相同的进行处理, 23 for (int i=1;i<=n;++i) 24 for (int j=i+1;j<=n;++j) 25 if (Matrix[0].Row[i]!=Matrix[0].Row[j]) 26 { if (i+1==j) break; 27 else{qSort2(i,j-1);//按列指标对答案矩阵三元组QuickSort 28 i=j-1; 29 break; 30 } 31 } */ 32 ///我这一段排序好像有点儿bug,一开始Test的时候是对的,交报告前随便写了个点儿发现错了、23333求大神帮忙指正 33 }
6.输出模块OutputData();
1 void OutputData() 2 { 3 for (int i=1;i<=n;++i) 4 { //合并格元素,已被用的行列指标赋值-1标记 5 if (Matrix[0].Row[i]==Matrix[0].Row[i+1] && Matrix[0].Column[i]==Matrix[0].Column[i+1]) 6 { 7 Matrix[0].Row[i]=Matrix[0].Column[i]=-1; 8 Matrix[0].Data[i+1]+=Matrix[0].Data[i]; 9 } 10 } 11 cout<<"按照读入三元组方式输出答案"<<endl; 12 for (int i=1;i<=n;++i) 13 { 14 if (Matrix[0].Row[i]!=-1) 15 { 16 cout<<"Ans["<<Matrix[0].Row[i]<<','; 17 cout<<Matrix[0].Column[i]<<"]="<<Matrix[0].Data[i]<<endl; 18 } 19 } 20 cout<<"按照矩阵方式输出答案"<<endl; 21 ///因为Matrix[0]已排序,故可顺次输出;不存在的即输出0; 22 int S=1; 23 for (int i=1;i<=Matrix[0].Rows;++i) 24 { for (int j=1;j<=Matrix[0].Columns;++j) 25 { while (Matrix[0].Row[S]==-1) ++S; 26 if (Matrix[0].Row[S]!=i || Matrix[0].Column[S]!=j) 27 cout<<0<<'\t'; 28 else 29 { cout<<Matrix[0].Data[S]<<'\t'; 30 ++S; 31 } 32 } 33 cout<<' '<<endl; 34 } 35 }
7.完整代码
1 /* 2 By 3 Iris.Catch-22.S、` 4 Dept. of Mathematics, 5 School of Science, 6 HIT 7 December,2015 8 */ 9 #include<iostream> 10 using namespace std; 11 void CopyRight() 12 { 13 cout<<"------------By ICS,HIT,2015/12-------------"<<endl; 14 cout<<"---------------稀疏矩阵乘法----------------"<<endl; 15 cout<<"-----------------Ver 1.0.0-----------------"<<endl; 16 17 } 18 #define MAXVALUE 100000 19 #define N 2 20 struct _Matrix 21 { 22 int Sum;//总非零点数 23 int Rows,Columns;//行数,列数 24 double Data[MAXVALUE+1];//数据域,第i个数据的值 25 int Row[MAXVALUE+1],Column[MAXVALUE+1]; 26 //第i个数据是第Row[i]行,Column[i]列 27 }; 28 29 /*新建矩阵数组*/ 30 _Matrix Matrix[N+1]; 31 int n; 32 33 /*Swap交换两个Double数*/ 34 void Swap(double &a,double &b) 35 { 36 double c=a; a=b; b=c; 37 } 38 /*重载Swap交换两个整数*/ 39 void Swap(int &a,int &b) 40 { 41 int c=a; a=b; b=c; 42 } 43 /*QuickSort 行排列从小到大*/ 44 void qSort(int l,int r) 45 { 46 int i=l; 47 int j=r; 48 int Mid=Matrix[0].Row[(l+r)>>1]; 49 do 50 { 51 while (Matrix[0].Row[i]<Mid) ++i; 52 while (Mid<Matrix[0].Row[j]) --j; 53 if (i<=j) 54 { 55 Swap(Matrix[0].Data[i],Matrix[0].Data[j]); 56 Swap(Matrix[0].Row[i],Matrix[0].Row[j]); 57 Swap(Matrix[0].Column[i],Matrix[0].Column[j]); 58 ++i; 59 --j; 60 } 61 } while (i<=j); 62 if (i<r) qSort(i,r); 63 if (l<j) qSort(l,j); 64 } 65 /*QuickSort 行相同,列排列从小到大*/ 66 void qSort2(int l,int r) 67 { 68 int i=l; 69 int j=r; 70 int Mid=Matrix[0].Column[(l+r)>>1]; 71 do 72 { 73 while (Matrix[0].Column[i]<Mid) ++i; 74 while (Mid<Matrix[0].Column[j]) --j; 75 if (i<=j) 76 { 77 Swap(Matrix[0].Data[i],Matrix[0].Data[j]); 78 Swap(Matrix[0].Column[i],Matrix[0].Column[j]); 79 ++i; 80 --j; 81 } 82 } while (i<=j); 83 if (i<r) qSort2(i,r); 84 if (l<j) qSort2(l,j); 85 } 86 87 /*初始化系数矩阵,Data,行、列矩阵指针Row、Column*/ 88 void Init() 89 { 90 for (int j=1;j<=N;++j) 91 for (int i=0;i<=MAXVALUE;++i) 92 Matrix[j].Data[i]=Matrix[j].Row[i]=Matrix[j].Column[i]=0; 93 } 94 /*读入数据*/ 95 void InputData(int i) 96 { 97 cout<<"请输入第"<<i<<"个矩阵"<<endl; 98 cout<<"请输入矩阵的行数和列数"<<endl; 99 cin>>Matrix[i].Rows>>Matrix[i].Columns; 100 cout<<"请依次输入矩阵元素,-1为结束标志"<<endl; 101 while (1) 102 { 103 cin>>Matrix[i].Row[++Matrix[i].Sum];//读入行指标,每读入一个非零元个数加1 104 if (Matrix[i].Row[Matrix[i].Sum]==-1)//-1为终止标志 105 { 106 --Matrix[i].Sum;//多读了个-1 107 break; 108 } 109 cin>>Matrix[i].Column[Matrix[i].Sum];//读入列数指标 110 cin>>Matrix[i].Data[Matrix[i].Sum];//读入系数值 111 } 112 } 113 114 /*测试输出*/ 115 /* 116 void COUT(int Head,int Tail) 117 { 118 cout<<"---------------------"<<Head<<' '<<Tail<<"--------------------"<<endl; 119 for (int i=Head;i<=Tail;++i) 120 cout<<Matrix[0].Row[i]<<' '<<Matrix[0].Column[i]<<' '<<Matrix[0].Data[i]<<endl; 121 cout<<"--------------------------------------------------"<<endl; 122 } 123 */ //测试输出 124 void MultiplyMatrix(int N1,int N2) 125 { 126 if (Matrix[N1].Columns != Matrix[N2].Rows) //判断是否可乘 127 { 128 cout<<"矩阵不可乘!请检查输入"<<endl; 129 return ; 130 } 131 Matrix[0].Rows=Matrix[N1].Rows; 132 Matrix[0].Columns=Matrix[N2].Columns; 133 //根据矩阵乘法规则确定所得答案矩阵行列指标 134 n=0;//初始化计数器 135 /*时间复杂度O(N1.Sum*N2.Sum)*/ 136 for (int i=1;i<=Matrix[N1].Sum;++i) 137 for (int j=1;j<=Matrix[N2].Sum;++j) 138 if (Matrix[N1].Column[i]==Matrix[N2].Row[j]) 139 //1矩阵列指标==2矩阵行指标时,相乘 140 { 141 Matrix[0].Data[++n]=Matrix[N1].Data[i]*Matrix[N2].Data[j]; 142 Matrix[0].Row[n]=Matrix[N1].Row[i];//行为1矩阵对应行 143 Matrix[0].Column[n]=Matrix[N2].Column[j];//列为2矩阵对应列 144 } 145 qSort(1,n);//按行指标对答案矩阵三元组进行QuickSort 146 /* 147 /*对行指标相同的进行处理*/ 148 //COUT(1,n); 149 for (int i=1;i<=n;++i) 150 for (int j=i+1;j<=n;++j) 151 if (Matrix[0].Row[i]!=Matrix[0].Row[j]) 152 { 153 if (i+1==j) break; 154 else 155 { 156 // COUT(i,j-1); 157 qSort2(i,j-1); 158 //COUT(i,j-1); 159 i=j-1; 160 break; 161 } 162 } 163 */ ///本段待修正、、、、、 164 } 165 void OutputData() 166 { 167 /* 168 for (int i=1;i<=n;++i) 169 { 170 if (Matrix[0].Row[i]!=-1) 171 cout<<Matrix[0].Data[i]<<'-'<<Matrix[0].Row[i]<<'-'; 172 cout<<Matrix[0].Column[i]<<endl; 173 } 174 */ //原始数据 175 for (int i=1;i<=n;++i) 176 { 177 if(Matrix[0].Row[i]==Matrix[0].Row[i+1]&&Matrix[0].Column[i]==Matrix[0].Column[i+1]) 178 { 179 Matrix[0].Row[i]=Matrix[0].Column[i]=-1; 180 Matrix[0].Data[i+1]+=Matrix[0].Data[i]; 181 } 182 } 183 cout<<"按照读入三元组方式输出答案"<<endl; 184 for (int i=1;i<=n;++i) 185 { 186 if (Matrix[0].Row[i]!=-1) 187 cout<<"Ans["<<Matrix[0].Row[i]<<','<<Matrix[0].Column[i]<<"]="<<Matrix[0].Data[i]<<endl; 188 } 189 /* cout<<"按照读入矩阵方式输出答案"<<endl; 190 int S=1; 191 for (int i=1;i<=Matrix[0].Rows;++i) 192 { for (int j=1;j<=Matrix[0].Columns;++j) 193 { 194 while (Matrix[0].Row[S]==-1) ++S; 195 if (Matrix[0].Row[S]!=i || Matrix[0].Column[S]!=j) 196 cout<<0<<'\t'; 197 else 198 { 199 cout<<Matrix[0].Data[S]<<'\t'; 200 ++S; 201 } 202 } 203 cout<<' '<<endl; 204 } 205 }*/ 206 int main() 207 { CopyRight(); 208 cout<<"读入方法如下:"<<endl; 209 cout<<"输入矩阵的行数和列数"<<endl; 210 cout<<"然后依次读入元素"<<endl; 211 cout<<"第i行,第j列的值为Value"<<endl; 212 cout<<"则输入i j Value"<<endl; 213 cout<<"输入-1时结束对本矩阵读入"<<endl; 214 cout<<"如对矩阵12 0 0"<<endl; 215 cout<<" 0 0 1"<<endl; 216 cout<<" 0 0 0"<<endl; 217 cout<<"请输入:3 3 "<<endl; 218 cout<<"请输入:1 1 12"<<endl; 219 cout<<" 2 3 1 "<<endl; 220 cout<<" -1 "<<endl; 221 Init(); 222 for (int i=1;i<=N;++i) 223 InputData(i); 224 MultiplyMatrix(1,2); 225 OutputData(); 226 return 0; 227 }
......
反正排序又被我搞的乱七八糟的……
QSort程序还是学期初手改的当初省实验王乃广老师教的那个快排(233333333)
然后对Qsort没什么心情研究了
结果今年DataStructure居然玩漏了没时间讲Sort了……
话说HuffManTree啊、查找啊、排序啊、什么的不都可以在算法课讲吗(hhhhh我知道你歧视小学期)
唉、
-----Done By Iris.Catch-22.S、`