数据结构:特殊矩阵的处理

一道简单的数据结构题目。题目描述如下:

特殊矩阵在采用二维数组存储时,尽管矩阵操作的算法都很简单,但是其空间的利用率很低。 系数矩阵就是一种应用很广泛的特殊的矩阵。现要求稀疏矩阵采用“压缩”存储,实现矩阵的常用操作,如输出、转置、求和等。

矩阵的输入:有多行,第1行包括三个整数,分别是矩阵的大小m,n及非零元素的个数r。

                      后面r行分别输入各个非零元素的 行、列、值

矩阵的输出:按人们习惯的矩阵格式输出,即输出一个m*n的矩阵,是零元素的输出0,非零元素输出元素值。

例如:输入如下:

输入Result
100 90 5
1 10 100
50 60 200
50 80 100
60 60 200
99 89 10
100 90 4
1 1 10
50 60 -200
50 80 100
70 70 10
The transformed matrix  is:
10 1 100
60 50 200
60 60 200
80 50 100
89 99 10
The added matrix is:
1 1 10
1 10 100
50 80 200
60 60 200
70 70 10
99 89 10

 

这道题比较简单,只输入两个稀疏矩阵,要求对第一个矩阵进行转置,对两个矩阵相加。

      在计算机中存储矩阵一般都用二位数组,它的有点是可以随机访问每一个元素,缺点是如果输入的是特殊矩阵(如稀疏矩阵)会造成大量的空间浪费,而且对于某些需要遍历矩阵的算法来说会耗费大量的时间,显然是不可取的。所以,对于稀疏矩阵,必须考虑对其压缩存储。一种较好的方法是:只存储在矩阵中极少的非零元素,为此,必须对每一个非零元素保存其下标和值。可以采用一个三元组<row,column,value>来唯一的确定一个矩阵元素,因此,稀疏矩阵需要用一个三元组数组来表示。在该数组中,个矩阵元素的三元组按在原矩阵中的位置,以行优先的规则依次存放,另外还要存储原矩阵的行数、列数和非零元素的个数。以上是稀疏矩阵的定义和存储。对于系数矩阵的转置,可以新定义一个三元组表,将新定义的三元组表的行数和列数与目标矩阵的列数和行数互换,value的值不变,假设原三元组表有cols列,当cols列扫描完成,算法结束;两个矩阵相加,其前提条件是两个矩阵大小相同,即行数和列数相同,本题不存在行数和列数不相同的问题。矩阵的加法,各位朋友可以去问度娘,当然输出需要按照行的大小进行排列然后输出。

完整代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;


struct Trituple{//三元组结构体
    int row,col;
    int value;
};

class SparseMatrix{//三元组表类
public:
    int Rows,Cols,Terms;
    Trituple *thArray;
public:
    SparseMatrix(int x,int y,int z);
    SparseMatrix(){thArray = new Trituple[1001];}
    ~SparseMatrix(){delete[] thArray;}
    void Transpose();//转置函数
    void Add(SparseMatrix &b);//矩阵相加函数
};

void SparseMatrix::Add(SparseMatrix &b){
    SparseMatrix result;

    result.Rows = Rows;
    result.Cols = Cols;
    result.Terms = 0;

    int i=0,j=0,index_a,index_b;
    while(i<Terms&&j<b.Terms){
        /*
        用index_a和index_b来比较里两个元素在原矩阵中的位置,因为矩阵大小相同,实际上这比的是
        两个元素谁更靠前
        */
        index_a = Cols*thArray[i].row + thArray[i].col;
        index_b = Cols*b.thArray[j].row + b.thArray[j].col;
        if(index_a<index_b){
            result.thArray[result.Terms] = thArray[i];
            i++;
        }
        else if(index_a>index_b){
            result.thArray[result.Terms] = b.thArray[j];
            j++;
        }
        else{
            if((thArray[i].value + b.thArray[j].value)!=0){
                result.thArray[result.Terms] = thArray[i];
                result.thArray[result.Terms].value = thArray[i].value + b.thArray[j].value;
                i++;j++;
            }
            //else的意思是存在两个value相加为零的情况,如果为零则继续循环,Terms不用加1
            else{i++;j++;continue;}
        }
        result.Terms++;
    }
    //复制剩余的元素
    for(;i<Terms;i++){
        result.thArray[result.Terms] = thArray[i];
        result.Terms++;
    }

    for(;j<b.Terms;j++){
        result.thArray[result.Terms] = b.thArray[j];
        result.Terms++;
    }

    //输出结果
    printf("The added matrix is:\n");
    for(int i=0;i<result.Terms;i++){
        printf("%d %d %d\n",result.thArray[i].row,result.thArray[i].col,result.thArray[i].value);
    }
}
//构造函数赋初值,将矩阵的行数、列数以及非零元素的个数赋给相应的成员变量
SparseMatrix::SparseMatrix(int x,int y,int z){
    Rows = x;Cols = y;Terms = z;
    thArray = new Trituple[z+1];
}
//实现转置函数
void SparseMatrix::Transpose(){
    SparseMatrix b(Cols,Rows,Terms);

    int k,i,CurrentB=0;
    for(k=0;k<Cols;k++){
        for(i=0;i<Terms;i++){
            if(thArray[i].col==k){
                b.thArray[CurrentB].row = k;
                b.thArray[CurrentB].col = thArray[i].row;
                b.thArray[CurrentB].value = thArray[i].value;
                CurrentB++;
            }
        }
    }
    //输出结果
    printf("The transformed matrix  is:\n");
    for(i=0;i<Terms;i++){
        printf("%d %d %d\n",b.thArray[i].row,b.thArray[i].col,b.thArray[i].value);
    }
}
int main()
{
    int m1,n1,r1,m2,r2,n2;

    scanf("%d %d %d",&m1,&n1,&r1);
    SparseMatrix a(m1,n1,r1);
    for(int i=0;i<a.Terms;i++){
        scanf("%d %d %d",&a.thArray[i].row,&a.thArray[i].col,&a.thArray[i].value);
    }
    scanf("%d %d %d",&m2,&n2,&r2);
    SparseMatrix b(m2,n2,r2);
    for(int j=0;j<b.Terms;j++){
        scanf("%d %d %d",&b.thArray[j].row,&b.thArray[j].col,&b.thArray[j].value);
    }
    a.Transpose();
    a.Add(b);
    return 0;
}

有不明白的问题可以在下方留言哦,也欢迎各位朋友批评指正代码中不正确的地方。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值