实验5:特殊矩阵的处理

稀疏矩阵ADT的实现:

在现实应用中,一些规模很大的特殊矩阵具有重要的地位。特殊矩阵可以采用二维数组存储,简单直接(顺序存储方式保持了矩阵中元素之间的二维线性关系),矩阵操作的算法都很简单,但是其空间的利用率很低(因为重复元素或零元素比较多)。 稀疏矩阵就是一种应用很广泛的特殊的矩阵,在实现稀疏矩阵ADT时通常采用“压缩”存储方案,即把只存储稀疏矩阵的非零元素,把稀疏矩阵抽象成为一个以三元组(行,列,值)为数据元素的线性表来处理,而我们知道:线性表可以采用顺序存储,也可以采用链式存储(通常用十字链表)。

现要求编程实现稀疏矩阵在“压缩”存储时的常用操作,如输出、转置、求和、乘等。(注:在代码注释中说明你采用的存储结构)

需要输入两个矩阵,完成:

(1) 转置。对第一个矩阵进行转置并输出,前面输出标题 “The transformed matrix is:”

(2) 矩阵加。如两个矩阵可以相加,进行两个矩阵加并输出,前面输出标题 “The added matrix is:”

               如果不能相加输出 “Can not add!”;

(3) 矩阵乘。如果两个矩阵可以相乘,进行两个矩阵乘并输出,前面输出标题 “The product matrix is:”

                    如果不能相乘输出 “Can not multiply!”

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

矩阵的输出:有两种形式,操作时分别用符号“L”、“H”指出输出形式。

L: 以三元组的形式输出,即先输出矩阵的行数、列数和非零元素个数,再依次输出各个非零元素的行、列和值。

H: 按人们习惯的矩阵格式输出,即输出一个m*n的矩阵,是零元素的输出0,非零元素输出元素值。设定每个元素占位宽度为4。(要输出行号和列号,并对齐)

刚开始用的vector持续程序错误 应该是哪里vector访问越界了 改了好久气哭呜呜呜

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
map<pii,int>::iterator it;
class Matrix{
public:
    int n,m,r;
    map<pii,int>mp;

    Matrix(int n,int m,int r);
    void Create();
    void Print(int op);
    void Add(Matrix &B,int op);
    void Mul(Matrix &B,int op);
    void Tran(int op);
};
Matrix::Matrix(int n, int m, int r) {
    this->n = n;
    this->m = m;
    this->r = r;
}
void Matrix::Create() {
    int x,y,z;
    for (int i=0;i<r;++i){
        cin>>x>>y>>z;
        mp[make_pair(x,y)] = z;
    }
}
void Matrix::Print(int op) {
    if (op){
        for (int i=1;i<=4;++i) printf(" ");
        for (int i=1;i<=m;++i) printf("%4d",i);
        puts("");
        for (int i=1;i<=n;++i){
            printf("%4d",i);
            for (int j=1;j<=m;++j){
                pii tmp = make_pair(i,j);
                if (mp.find(tmp) != mp.end()){
                    printf("%4d",mp[tmp]);
                }
                else printf("%4d",0);
            }
            puts("");
        }
    }
    else {
        r = 0;
        for (it = mp.begin();it != mp.end();++it){
            if (it->second) r++;
        }
        printf("Rows=%d,Cols=%d,r=%d\n",n,m,r);
        for (it = mp.begin();it != mp.end();it++){
            if (it->second){
                printf("%d %d %d\n",it->first.first,it->first.second,it->second);
            }
        }
    }
}
void Matrix::Add(Matrix &B, int op) {
    if (B.n != n || B.m != m) {
        printf("Can not add!\n");
        return ;
    }
    Matrix C(n,m,r);
    for (int i=0;i<r;i++){
        C.mp = mp;
    }
    for (it = B.mp.begin();it != B.mp.end();++it){
        C.mp[it->first] += it->second;
    }
    printf("The added matrix is:\n");
    C.Print(op);
}

void Matrix::Mul( Matrix &B, int op) {
    if (m != B.n) {
        printf("Can not multiply!");
        return ;
    }
    Matrix C(n,B.m,0);
    for (int i=1;i<=n;++i){
        for (int j=1;j<=B.m;++j){
            int sum = 0;
            pii now = make_pair(i,j);
            for (int k=1;k<=m;++k){
                pii x = make_pair(i,k), y = make_pair(k,j);
                if (mp.find(x) == mp.end() || B.mp.find(y) == mp.end()) continue;
                sum += mp[x] * B.mp[y];
            }
            if (sum) C.mp[now] = sum;
        }
    }
    printf("The product matrix is:\n");
    C.Print(op);
}

void Matrix::Tran(int op) {
    Matrix B(m,n,r);
    for (it = mp.begin();it != mp.end(); ++it){
        pii x = it->first;
        pii y = make_pair(x.second,x.first);
        B.mp[y] = it->second;
    }
    printf("The transformed matrix is:\n");
    B.Print(op);
}

int main (){
    int x,y,r,op;
    string s;
    cin>>x>>y>>r;
    Matrix A(x,y,r);
    A.Create();
    cin>>x>>y>>r;
    Matrix B(x,y,r);
    B.Create();
    cin>>s;
    if (s[0] == 'L') op = 0;
    else op = 1;
    A.Tran(op);
    A.Add(B,op);
    A.Mul(B,op);
    return 0;
}
/*
2 2 4
1 1 1
1 2 2
2 1 3
2 2 1
2 2 3
1 1 1
2 1 1
2 2 1
H
 */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值