zoukankan      html  css  js  c++  java
  • [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<<'	';
    28             else
    29             { cout<<Matrix[0].Data[S]<<'	';
    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<<'	';
    197             else
    198             {
    199               cout<<Matrix[0].Data[S]<<'	';
    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、`

  • 相关阅读:
    括号序列
    秘密信息
    大奖赛
    订单
    摆花
    利用spring自己实现观察者模式
    Spring操作mongo排序,限制查询记录数
    Hbse的读写过程
    使用aop记录数据库操作的执行时间
    分享一个关于jackson的Json工具类
  • 原文地址:https://www.cnblogs.com/Catch-22/p/5092819.html
Copyright © 2011-2022 走看看