三元组类与稀疏矩阵运算--c++【做题记录】

实现三元组类

【题目要求】

按照给定的内容定义一个TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息。

 输入:第一行输入矩阵的行m,列n和非零元个数num 后续num行依次输入每个非零元的行,列和非零元的值 。

输出:首先显示三元组数组的内容,数字之间间隔一个空格。 然后以二维数组形式排列的稀疏矩阵效果,数字之间间隔一个空格。 输出稀疏矩阵的基本信息:行数,列数和非零元个数。

【测试样例】

【样例输入】

3 4 4

1 1 2

3 4 1

2 1 13

2 2 -1

【样例输出】

Print triple array.

row col item

1 1 2 2

1 13 2 2

-1 3 4 1

Print sparse matrix.

2 0 0 0

13 -1 0 0

0 0 0 1

line=3,column=4,nonzero number=4

【提示】

将输入的行、列、非零元素信息插入到三元组的思路提示:

  1. 如果是第一次输入,i=0时,则直接插入。
  2. 如果不是第一次输入,则应该考虑插入到什么位置,三元组数据的排序是优先考虑行,然后考虑列。
  3. 找到插入位置后,例如需要插入在j的地方,则需要考虑是否需要将已有三元组后续的元素后移,为j腾出空间,然后再插入。 需要考虑一些特殊的情况: 输入时行号列号不按顺序,输入重复的行号和列号,则重复输入的数据只记录后者。

【题解代码】

/*
用三元组存储稀疏矩阵,仅实现稀疏矩阵类并显示
*/
//用三元组存储稀疏矩阵(仅存储,不计算)

#include <iostream>
using namespace std;
#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型
typedef struct{
    int row,col;    //三元组的行号、列号;
    int item;        //三元组的值;
}Triple;
//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix{
private:
    Triple data[MAX];//非零元三元组
    int mu,nu,num;   //矩阵的行数、列数和非零元个数
public:
    TripleMatrix();
    TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
    ~TripleMatrix();
    Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
    int getItem(int row,int col);//根据行号列号,获得矩阵元素值
    void printMatrix();//按矩阵方式打印稀疏矩阵
    void printTriple();//打印三元组数组
};
//填写代码实现三元组类中的成员函数 
TripleMatrix::TripleMatrix()
{
    mu=0;
    nu=0;
    num=0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
    nu=n;
    mu=m;
    num=0;
}
TripleMatrix::~TripleMatrix()
{
    //使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
    if(row>mu||col>nu)//超范
        return ERROR;
    if(num==MAX)//即将超范
        return ERROR;
    if(item==0)//为0时不需要存储
        return OK;
    
    int index=0;
    while(index<num)
    {
        if(row>data[index].row)//要找的行和列比三元组中已有的行列大
            index++;
        else if(row==data[index].row&&col>data[index].col)//要找的行号相等,列不相等,继续找列
            index++;
        else{                 //找到了应该插入的位置
            break;
        }
    }
    if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
        data[index].item=item;
    else                      //需要插入新元素
    {
        for(int i=num;i>index;i--)//先从后往前把后面所有的元素向后以腾出新元素的位置
        {
            data[i].row=data[i-1].row;            //可以简化成data[i]=data[i-1];
            data[i].col=data[i-1].col;
            data[i].item=data[i-1].item;
        }
        //再在index的位置存入新元素
        data[index].row=row;
        data[index].col=col;
        data[index].item=item;
        num++;
    }
    return OK;
}
int TripleMatrix::getItem(int row,int col)
{
    if(row>mu||col>nu)
        return 0;
    for(int i=0;i<num;i++)//如果行和列匹配三元组,返回非零元
    {
        if(data[i].row==row&&data[i].col==col)
        {
            return data[i].item;
        }
    }
}
void TripleMatrix::printMatrix()
{
    int tripleindex=0;
    cout<<"Print sparse matrix.\n";
    for(int i=1;i<=mu;i++)
    {
        for(int j=1;j<=nu;j++)
        {
            if(i==data[tripleindex].row&&j==data[tripleindex].col)
            {                                     //如果找到了行列号匹配的三元组就输出非零元
                cout<<data[tripleindex].item;   
                tripleindex++;
                if(j<nu)
                    cout<<" ";
            }
            else
                cout<<"0 ";
        }
        cout<<endl;
    }
    cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<num;
    return ;
}
void TripleMatrix::printTriple()
{
    cout<<"Print triple array."<<endl;
    cout<<"row col item"<<endl;
    for(int i=0;i<num;i++)
    {
        cout<<data[i].row<<" ";
        cout<<data[i].col<<" ";
        cout<<data[i].item<<endl;
    }
}

//输入函数
void inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
    int row,col,item;
    for(int i=1;i<=num;i++)
    {
        cout<<"输入行列和非零元:\n";
        cin>>row>>col>>item;
        if(item!=0)
        {
            if(triple.setItem(row,col,item)==ERROR)
            {
                cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
                break;
            }
        }
    }
}

int main(){
    int m,n,num;
    cout << "请输入矩阵的行,列和非零元个数:";
    cin >> m >> n >> num;
    TripleMatrix triple(m,n);
    inputMatrix(m,n,num,triple);
    triple.printTriple();
    triple.printMatrix();
    return 0;
}

稀疏矩阵加法

【题目要求】

实现稀疏矩阵的加法,输入任意两个稀疏矩阵A和B,求出它们的和矩阵C。

实现步骤是:

(1) 创建三个稀疏矩阵。

(2)实现加法运算。

(3)输出稀疏矩阵相加的结果。

[输入说明] 第一行输入第一个矩阵的行n,列m,非零元素个数num(行列的序号从1开始) 后续num行依次输入行row,列col和非零元item 接着输入第二个矩阵的行n,列m,非零元素个数num 后续num行依次输入行row,列col和非零元item

[输出说明] 需要对输入的两个矩阵进行检查,仅有行列相同的矩阵才能相加。 如果矩阵可以相加,则在矩阵相加后,打印矩阵内容。并显示矩阵行列数和非零元个数。 如果矩阵不能相加,则提示错误:Matrices cannot be added. 

【测试样例】

【输入数据1】

3 3 2

1 1 5

2 3 1

3 3 4

1 1 5

1 2 6

3 2 1

2 1 1

【输出数据1】

After add:

10 6 0

1 0 1

0 1 0

line=3,column=3,nonzero number=5

【输入数据2】

3 3 2

1 1 5

2 3 1

3 2 2

1 1 5

1 2 6

【输出数据2】

Matrices cannot be added.

【题解代码】

/*
用三元组存储稀疏矩阵,并完成加法(头歌使用的例子)
这个例子输入行号,列号,非零元,再存储
*/

#include <iostream>
using namespace std;

#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型

typedef struct{
    int row,col;    //三元组的行号、列号;
    int item;        //三元组的值;
}Triple;

//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix{
private:
    Triple data[MAX];//非零元三元组
    int mu,nu,num;   //矩阵的行数、列数和非零元个数
public:
    TripleMatrix();
    TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
    ~TripleMatrix();
    Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
    int getItem(int row,int col);//根据行号列号,获得矩阵元素值
    void printMatrix();//按矩阵方式打印稀疏矩阵
    void printTriple();//打印三元组数组
    void inputMatrix(int m,int n,int num,TripleMatrix& triple);
    friend bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result);
};

TripleMatrix::TripleMatrix(){
    //初始化矩阵的行数、列数和非零元个数
    mu = 0;
    nu = 0;
    num = 0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
    nu=n;
    mu=m;
    num=0;
}
//自己填写代码实现三元组类
TripleMatrix::~TripleMatrix()
{
    //使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
    if(row>mu||col>nu)//超范
        return ERROR;
    if(num==MAX)//即将超范
        return ERROR;
    if(item==0)//为0时不需要存储
        return OK;

    int index=0;
    while(index<num)
    {
        if(row>data[index].row)//要找的行和列比三元组中已有的行列大
            index++;
        else if(row==data[index].row&&col!=data[index].col)//要找的行号相等,列不相等,继续找列
            index++;
        else{                 //找到了应该插入的位置
            break;
        }
    }
    if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
        data[index].item=item;
    else                      //需要插入新元素
    {
        for(int i=num;i>index;i--)//先从后往前把后面所有的元素向后移腾出新元素的位置
        {
            data[i].row=data[i-1].row;            //可以简化成data[i]=data[i-1];
            data[i].col=data[i-1].col;
            data[i].item=data[i-1].item;
        }
        //再在index的位置存入新元素
        data[index].row=row;
        data[index].col=col;
        data[index].item=item;
        num++;
    }
    return OK;
}
int TripleMatrix::getItem(int row,int col)
{
    if(row>mu||col>nu)
        return 0;
    for(int i=0;i<num;i++)//如果行和列匹配三元组,返回非零元
    {
        if(data[i].row==row&&data[i].col==col)
        {
            return data[i].item;
        }
    }
    return 0;
}
void TripleMatrix::printMatrix()
{
    int tripleindex=0;
    int count=0;//记录非零元个数
    cout<<"Print sparse matrix.\n";
    for(int i=1;i<=mu;i++)
    {
        for(int j=1;j<=nu;j++)
        {
            if(i==data[tripleindex].row&&j==data[tripleindex].col)
            {                                     //如果找到了行列号匹配的三元组就输出非零元
                cout<<data[tripleindex].item;
                tripleindex++;
                count++;
                if(j<nu)
                    cout<<" ";
            }
            else{
                cout<<"0";
                if(j<nu)
                    cout<<" ";
            }
                
        }
        cout<<endl;
    }
    cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<count;
    return ;
}
void TripleMatrix::printTriple()
{
    cout<<"Print triple array."<<endl;
    cout<<"row col item"<<endl;
    for(int i=0;i<num;i++)
    {
        cout<<data[i].row<<" ";
        cout<<data[i].col<<" ";
        cout<<data[i].item;
        if(i<num-1)
            cout<<endl;
    }
}
//输入函数
void TripleMatrix::inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
    int row,col,item;
    for(int i=1;i<=num;i++)
    {
        //cout<<"输入行列和非零元:\n";
        cin>>row>>col>>item;
        if(item!=0)
        {
            if(triple.setItem(row,col,item)==ERROR)
            {
                cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
                break;
            }
        }
    }
}
/*
实现矩阵a与矩阵b的相加,结果放入矩阵result
如果矩阵可以相加,完成相加操作,结果放入result,并返回true
如果矩阵不能相加,返回false
*/
bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result){
//
    if(a.mu!=b.mu||b.mu!=result.mu||a.nu!=b.nu||b.nu!=result.nu)
        return false;             //判断矩阵ab或result行列是否相等
    else{
        for(int i=1;i<=a.mu;i++)  //遍历行
        {
            for(int j=1;j<=a.nu;j++)   //遍历列
            {
                int item=a.getItem(i,j)+b.getItem(i,j);
                if(item!=0)
                    result.setItem(i,j,item);   //将非零元插入
            }
        }
        return true;
    }
}

/*加法的测试代码*/
int main(){
    int m,n,num;
    cout << "请输入第一个矩阵的行,列,非零元素个数:";
    cin >> m >> n >> num;
    cout << "第一个矩阵:"<< endl;
    TripleMatrix tripleA(m,n);
    tripleA.inputMatrix(m,n,num,tripleA);
    // tripleA.printMatrix();

    cout<<"\n请输入第二个矩阵的行,列,非零元个数:";
    cin>>m>>n>>num;
    cout<<"第二个矩阵:"<<endl;
    TripleMatrix tripleB(m,n);
    tripleB.inputMatrix(m,n,num,tripleB);
    // tripleB.printMatrix();

    TripleMatrix tripleResult(m,n);
    if(matrixAdd(tripleA,tripleB,tripleResult))
    {
        cout<<"After add:"<<endl;
        tripleResult.printMatrix();
    }
    else
        cout<<"Matrices cannot be added.";

    return 0;
}

稀疏矩阵乘法

【题目要求】

输入任意两个稀疏矩阵A和B,求出它们的乘积矩阵C。

实现步骤是:

(1) 创建三个稀疏矩阵。

(2) 实现乘法运算。

(3) 输出稀疏矩阵相乘的结果。

[输入说明] 第一行输入第一个矩阵的行n,列m,非零元素个数num 后续num行依次输入行row,列col和非零元item 接着输入第二个矩阵的行n,列m,非零元素个数num 后续num行依次输入行row,列col和非零元item

[输出说明] 需要对输入的两个矩阵进行检查,仅有符合矩阵相乘规则的矩阵才能相乘。 如果矩阵可以相乘,则在矩阵相乘后,打印矩阵内容。并显示矩阵行列数和非零元个数。 如果矩阵不能相乘,则提示错误:Matrices cannot be multiplied.

(这个题和上面的加法基本思路一样的,只需要改求和函数为求积函数即可)

【测试样例】

【输入数据】

3 3 2

1 1 5

2 3 1

3 2 2

1 1 2

3 1 4

【输出范例】

After Multiply:

10 0

4 0

0 0

line=3,column=2,nunzero number=2

【题解代码】



#include <iostream>
using namespace std;

#define MAX 100
#define ERROR 0
#define OK 1
typedef int Status;//函数结果状态类型

typedef struct
{
    int row,col;    //三元组的行号、列号;
    int item;        //三元组的值;
} Triple;

//定义TripleMatrix类,每个TripleMatrix对象访问一个矩阵的信息
class TripleMatrix
{
private:
    Triple data[MAX];//非零元三元组
    int mu,nu,num;   //矩阵的行数、列数和非零元个数
public:
    TripleMatrix();
    TripleMatrix(int m,int n);//创建对象时,完成属性的初始化
    ~TripleMatrix();
    Status setItem(int row,int col,int item);//根据行号,列号,非零元,在尾部添加一个三元组项
    int getItem(int row,int col);//根据行号列号,获得矩阵元素值
    void printMatrix();//按矩阵方式打印稀疏矩阵
    void printTriple();//打印三元组数组
    void inputMatrix(int m,int n,int num,TripleMatrix& triple);
    friend bool matrixAdd(TripleMatrix a,TripleMatrix b,TripleMatrix& result);
    friend bool matrixMulty(TripleMatrix a,TripleMatrix b,TripleMatrix &result);
};

TripleMatrix::TripleMatrix()
{
    //初始化矩阵的行数、列数和非零元个数
    mu = 0;
    nu = 0;
    num = 0;
}
TripleMatrix::TripleMatrix(int m,int n)
{
    nu=n;
    mu=m;
    num=0;
}
//自己填写代码实现三元组类
TripleMatrix::~TripleMatrix()
{
    //使用的是静态数组,可以不用析构函数
}
Status TripleMatrix::setItem(int row,int col,int item)
{
    if(row>mu||col>nu)//超范
        return ERROR;
    if(num==MAX)//即将超范
        return ERROR;
    if(item==0)//为0时不需要存储
        return OK;

    int index=0;
    while(index<num)
    {
        if(row>data[index].row)//要找的行和列比三元组中已有的行列大
            index++;
        else if(row==data[index].row&&col!=data[index].col)//要找的行号相等,列不相等,继续找列
            index++;
        else                  //找到了应该插入的位置
        {
            break;
        }
    }
    if((row==data[index].row)&&col==data[index].col)//当前行列已有元素,用新插入的元素替换
        data[index].item=item;
    else                      //需要插入新元素
    {
        for(int i=num; i>index; i--) //先从后往前把后面所有的元素向后移腾出新元素的位置
        {
            data[i].row=data[i-1].row;            //可以简化成data[i]=data[i-1];
            data[i].col=data[i-1].col;
            data[i].item=data[i-1].item;
        }
        //再在index的位置存入新元素
        data[index].row=row;
        data[index].col=col;
        data[index].item=item;
        num++;
    }
    return OK;
}
int TripleMatrix::getItem(int row,int col)
{
    if(row>mu||col>nu)
        return 0;
    for(int i=0; i<num; i++) //如果行和列匹配三元组,返回非零元
    {
        if(data[i].row==row&&data[i].col==col)
        {
            return data[i].item;
        }
    }
    return 0;
}
void TripleMatrix::printMatrix()
{
    int tripleindex=0;
    int count=0;//记录非零元个数
    // cout<<"Print sparse matrix.\n";
    for(int i=1; i<=mu; i++)
    {
        for(int j=1; j<=nu; j++)
        {
            if(i==data[tripleindex].row&&j==data[tripleindex].col)
            {
                //如果找到了行列号匹配的三元组就输出非零元
                cout<<data[tripleindex].item;
                tripleindex++;
                count++;
                if(j<nu)
                    cout<<" ";
            }
            else
            {
                cout<<"0";
                if(j<nu)
                    cout<<" ";
            }

        }
        cout<<endl;
    }
    cout<<"line="<<mu<<",column="<<nu<<",nonzero number="<<count;
    return ;
}
void TripleMatrix::printTriple()
{
    cout<<"Print triple array."<<endl;
    cout<<"row col item"<<endl;
    for(int i=0; i<num; i++)
    {
        cout<<data[i].row<<" ";
        cout<<data[i].col<<" ";
        cout<<data[i].item;
        if(i<num-1)
            cout<<endl;
    }
}
//输入函数
void TripleMatrix::inputMatrix(int m,int n,int num,TripleMatrix& triple)
{
    int row,col,item;
    for(int i=1; i<=num; i++)
    {
        //cout<<"输入行列和非零元:\n";
        cin>>row>>col>>item;
        if(item!=0)
        {
            if(triple.setItem(row,col,item)==ERROR)
            {
                cout<<"行列号不正确,或三元数组满,不能正确存储"<<endl;
                break;
            }
        }
    }
}

bool matrixMulty(TripleMatrix a,TripleMatrix b,TripleMatrix& result)
{
//
    int i,j,k;
    if(a.nu!=b.mu)           //判断是否满足可以相乘的条件,a列数等于b行数才能相乘
        return false;
    result.mu=a.mu;          //初始化result的行列值
    result.nu=b.nu;
    //乘法计算
    for(i=1; i<=a.mu; i++)
    {
        for(j=1; j<=b.nu; j++)
        {
            int sum=0;
            for(k=1; k<=a.nu; k++)
            {
                sum+=a.getItem(i,k)*b.getItem(k,j);
            }
            if(sum!=0)        //计算出来的值不为零才插入
                result.setItem(i,j,sum);
        }
    }
    return true;
}

int main()
{
    int m,n,num;
    cout << "请输入第一个矩阵的行,列,非零元素个数:";
    cin >> m >> n >> num;
    cout << "第一个矩阵:"<< endl;
    TripleMatrix tripleA(m,n);
    tripleA.inputMatrix(m,n,num,tripleA);
    tripleA.printMatrix();

    cout<<"\n输入第二个矩阵行,列,非零元个数:";
    cin>>m>>n>>num;
    cout<<"第二个矩阵"<<endl;
    TripleMatrix tripleB(m,n);
    tripleB.inputMatrix(m,n,num,tripleB);
    tripleB.printMatrix();

    TripleMatrix tripleResult;
    if(matrixMulty(tripleA,tripleB,tripleResult))
    {
        cout<<"After Multiply:"<<endl;
        tripleResult.printMatrix();
    }
    else
        cout<<"Matrices cannot be multiplied.";

    return 0;
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值