[DataStructure]稀疏矩阵的三元组存储及乘法运算

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、`

posted @ 2015-12-31 23:34  Iris.Catch-22.S、`  阅读(1201)  评论(0编辑  收藏  举报