稀疏矩阵ADT的实现:

2 篇文章 0 订阅

记给自己看别的就不多写了,记一个重要的测试用例

1 2 1
1 1 1
2 1 1
2 1 3
H

输出应该是

The transformed matrix is:
1
1 1
2 0
Can not add!
The product matrix is:
1
1 0

#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
typedef int ElemType;
struct Triple               //存储结构:顺序存储
{
    int row,col;
    ElemType value;
    void operator = (Triple & R)    //赋值
    {
        row=R.row;
        col=R.col;
        value=R.value;
    }
};
class SparseMatrix     //稀疏矩阵三元组类定义
{

    int maxcnts;
public:
    int Rows,Cols,Terms;      //矩阵一共有几行、几列、一共有几个非零元素
    Triple *smArray;         //三元组表,顺序存储
    SparseMatrix(int Rw,int,int Tm);  //构造函数
    SparseMatrix(int sz)
    {
        smArray=new Triple[sz];
        maxcnts=sz;
        Rows=0;
        Cols=0;
        Terms=0;
    }
    SparseMatrix Transpose();                          //转置
    bool Add(SparseMatrix& a,SparseMatrix &trans);                //矩阵加法
    bool Multiply(SparseMatrix& a,SparseMatrix &mul);           //矩阵乘法
};
SparseMatrix::SparseMatrix(int Rw,int Cl,int Tm)
{
    Rows=Rw;
    Cols=Cl;
    Terms=Tm;
}
SparseMatrix SparseMatrix::Transpose()
{
    SparseMatrix trans(100);
    trans.Rows=this->Cols;
    trans.Cols=this->Rows;
    trans.Terms=this->Terms;
    if(this->Terms>0)                             //非零个数不为零
    {
        int k,i,currentptr=0;
        for(k=1; k<=this->Cols; k++)               //列数遍历
        {
            for(i=0; i<this->Terms; i++)          //遍历非零数字
            {
                if(this->smArray[i].col == k)     //如果有非零数字是在这一列的
                {
                    //就让待输出的数组
                    trans.smArray[currentptr].row=k;//行等于这一列,列等于他的行,值相等
                    trans.smArray[currentptr].col=this->smArray[i].row;
                    trans.smArray[currentptr].value=this->smArray[i].value;
                    currentptr++;
                }
            }
        }
    }
    cout<<"The transformed matrix is:"<<endl;
    return trans;
}
bool SparseMatrix::Add(SparseMatrix &a,SparseMatrix &trans)
{
    if(this->Cols!=a.Cols || this->Rows!=a.Rows)
        {cout<<"Can not add!"<<endl; return 0;}
    else
    {
        trans.Cols=this->Cols;
        trans.Rows=this->Rows;
        trans.Terms=0;
        int i=0,j=0,k=0;
        if(this->Terms==0 && a.Terms!=0)
        {
            trans.Terms=a.Terms;
            for(int m=0; m<trans.Terms; m++)
            {
                trans.smArray[m]=a.smArray[m];
                trans.Terms++;
            }
            return 1;
        }
        else if(this->Terms!=0 && a.Terms==0)
        {
            trans.Terms=this->Terms;
            for(int m=0; m<trans.Terms; m++)
            {
                trans.smArray[m]=this->smArray[m];
                trans.Terms++;
            }
            return 1;
        }
        else if (this->Terms==0 && a.Terms==0)

        {
            return 1;
        }
        else
        {
            while(i<this->Terms && j<a.Terms)                 //两个都没遍历完
            {
                if(this->smArray[i].row >a.smArray[j].row)    //先看行数,行数小的直接放心新三元组
                {
                    trans.smArray[k]=a.smArray[j];
                    k++;
                    j++;
                    trans.Terms++;
                }
                else if(this->smArray[i].row <a.smArray[j].row)
                {
                    trans.smArray[k]=this->smArray[i];
                    k++;
                    i++;
                    trans.Terms++;
                }
                else if(this->smArray[i].row ==a.smArray[j].row)      //行数相等看列数
                {
                    if(this->smArray[i].col==a.smArray[j].col)        //如果列数相等,值相加
                    {
                        trans.smArray[k].row=this->smArray[i].row;
                        trans.smArray[k].col=this->smArray[i].col;
                        trans.smArray[k].value=this->smArray[i].value+a.smArray[j].value;
                        k++;
                        j++;
                        i++;
                        trans.Terms++;
                        if(trans.smArray[k-1].value==0)
                        {
                            k--;
                            trans.Terms--;
                        }
                    }
                    else if(this->smArray[i].col>a.smArray[j].col)   //如果列数不等,直接把列数小的放到新三元组
                    {
                        trans.smArray[k]=a.smArray[j];
                        k++;
                        j++;
                        trans.Terms++;
                    }
                    else if(this->smArray[i].col<a.smArray[j].col)
                    {
                        trans.smArray[k]=this->smArray[i];
                        k++;
                        i++;
                        trans.Terms++;
                    }
                }
            }                                                           //出了循环,至少有一个组已遍历完了
            while(i <this->Terms) //将this的遍历完
            {
                trans.smArray[k]=this->smArray[i];
                k++;
                i++;
                trans.Terms++;
            }
            while(j <a.Terms) //将a遍历完
            {
                trans.smArray[k]=a.smArray[j];
                k++;
                j++;
                trans.Terms++;
            }

        }
        cout<<"The added matrix is:"<<endl;
        return 1;
    }

}

bool SparseMatrix::Multiply(SparseMatrix &a,SparseMatrix &mul)
{

    if(this->Cols!=a.Rows)
    {
        cout<<"Can not multiply!"<<endl;
        return 0;
    }
    cout<<"The product matrix is:"<<endl;
    int p,j,q,i,r,k,t;

    mul.Rows=this->Rows;
    mul.Cols=a.Cols;                //确定乘积的行和列
    mul.Terms=0;
    if((this->Terms)*(a.Terms)==0)    //判断是否为零矩阵
    {
        return 1;
    }
    int temp[a.Cols+1];        //累加器
    int num[a.Rows+1],rpot[a.Rows+1];

    //计算右边矩阵中每行首位非零元素的位置
    for(i=1;i<=a.Rows;i++)    num[i]=0;      //num全部置零
    for(i=0;i<a.Terms;i++)
    {
        num[a.smArray[i].row]++;            //统计B每行非零个数
    }
    rpot[1]=0;
    for(i=2;i<=a.Rows;i++)
    {
        rpot[i]=rpot[i-1]+num[i-1];     //每一行第一个不为零数字的序数
    }
    r=0;          //指示乘积矩阵中非零元素的个数
    p=0;          //指示当前A矩阵中非零元素的位置

    //乘积运算
    for(i=1;i<=this->Rows;i++)                  //i遍历A的行
    {
        //累加器初始化
        for(j=1;j<=a.Cols;j++)
        {
            temp[j]=0;
        }

        //求Cij第i行元素的集合
        while(i==this->smArray[p].row)      //非0值在这一行 A的行时
        {
            k=this->smArray[p].col;        //获取A矩阵中第p个非零元素的列值

            if(k<a.Rows) t=rpot[k+1];      //确定B中的k行的非零元素在B.sm中的下限位置
            else t=a.Terms;

            for(q=rpot[k];q<t;q++)         //将B中第k行的每一列非零元素与A中非零元素记录到累加器中
            {
                j=a.smArray[q].col;
                temp[j]+=(this->smArray[p].value)*(a.smArray[q].value);
            }
            p++;
        }
        //将第i行的结果赋给成绩矩阵
        for(j=1;j<=a.Cols;j++)
        {
            if(temp[j]!=0)
            {
                mul.smArray[mul.Terms].row=i;
                mul.smArray[mul.Terms].col=j;
                mul.smArray[mul.Terms].value=temp[j];
                //cout<<mul.smArray[mul.Terms].row<<" "<<mul.smArray[mul.Terms].col<<" "<<mul.smArray[mul.Terms].value<<endl;
                mul.Terms++;

            }
        }
    }
    //mul.Terms=r;
    return 1;
}
void Lthree(SparseMatrix a)                   //三元组输出
{
    cout<<"Rows="<<a.Rows<<",Cols="<<a.Cols<<",r="<<a.Terms<<endl;
    int n=a.Terms;
    for(int i=0; i<n; i++)
    {
        cout<<a.smArray[i].row<<" "<<a.smArray[i].col<<" "<<a.smArray[i].value<<endl;
    }
}
void Hthree(SparseMatrix a)                    //矩阵输出
{
    int flag=0;
    cout<<"    ";
    for(int i=1; i<=a.Cols; i++)       //输出第一行
    {

        cout<<setw(4)<<right<<i;
    }
    cout<<endl;

    for(int i=1; i<=a.Rows; i++)
    {
        cout<<setw(4)<<right<<i;
        if(flag<a.Terms)                //还有非零元素没输出
        {
            if(i<a.smArray[flag].row)   //这一行没有非零
            {
                for(int j=1; j<=a.Cols; j++)       //输出一行0
                {

                    cout<<setw(4)<<right<<"0";
                }
            }
            else if(a.smArray[flag].row==i)  //这一行有非零
            {
                for(int j=1; j<=a.Cols; j++)       //列遍历
                {
                    if(a.smArray[flag].col==j && a.smArray[flag].row==i)     //找到了非零元素,输出
                    {
                        cout<<setw(4)<<right<<a.smArray[flag].value;
                        flag++;
                    }
                    else
                        cout<<setw(4)<<right<<"0";
                }
            }
            cout<<endl;
        }
        else
        {
            for(int j=1; j<=a.Cols; j++)       //输出一行0
                {

                    cout<<setw(4)<<right<<"0";
                }
                cout<<endl;
        }
    }
}
void choose (char c,SparseMatrix a)
{
    if (c=='L')
        Lthree(a);
    else if(c=='H')
        Hthree(a);

}
int main()
{
    bool flag;
    SparseMatrix a(100),a1(100),b(100);
    int h,l,n;
    char op;
    //cout<<"输入矩阵一共有几行 几列 几个非零元素"<<endl;
    cin>>h>>l>>n;
    a.Rows=h;
    a.Cols=l;
    a.Terms=n;
    for(int i=0; i<n; i++)
    {
        cin>>a.smArray[i].row;
        cin>>a.smArray[i].col;
        cin>>a.smArray[i].value;
    }
    //cout<<"输入矩阵一共有几行 几列 几个非零元素"<<endl;
    cin>>h>>l>>n;
    b.Rows=h;
    b.Cols=l;
    b.Terms=n;
    for(int i=0; i<n; i++)
    {
        cin>>b.smArray[i].row;
        cin>>b.smArray[i].col;
        cin>>b.smArray[i].value;
    }
    cin>>op;
    a1=a.Transpose();
    choose(op,a1);

    SparseMatrix trans(100);
    flag=a.Add(b,trans);
    if(flag==1)
    choose(op,trans);

    SparseMatrix mul(100);
    flag=a.Multiply(b,mul);
    if(flag==1)
    choose(op,mul);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值