实验5:特殊矩阵的处理

这篇博客介绍了如何处理特殊矩阵,特别是稀疏矩阵的ADT实现,包括转置、加法和乘法操作。作者使用结构体和数组实现,强调理解思路而非直接复制代码。文章提供样例输入和输出,以及AC代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*特殊矩阵的处理

实验五:稀疏矩阵ADT的实现:

总结: 没错,又是我,我又来水了。这个题目我认为就是一道模拟题,我就直接用结构体和数组谢了,思路就是简单的暴力,一步步的模拟过程。输出的格式要注意。希望读者们还是不要直接的copy,还是自己写一写,这只是一个思路。由于老师可能会增添样例,之后如果有新的样例的话,我的代码还会进行一定的修改。主要就是老师数据太水了,没卡掉我,哈哈哈。

在现实应用中,一些规模很大的特殊矩阵具有重要的地位。特殊矩阵可以采用二维数组存储,简单直接(顺序存储方式保持了矩阵中元素之间的二维线性关系),矩阵操作的算法都很简单,但是其空间的利用率很低(因为重复元素或零元素比较多)。 稀疏矩阵就是一种应用很广泛的特殊的矩阵,在实现稀疏矩阵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。(要输出行号和列号,并对齐)

样例1:

10 8 4 //第1个矩阵 10行,8列,4个非零元素
1 8 1 //第1行第8列元素值为1
3 3 2 //第3行第3列元素值为2
3 7 3 //第3行第7列元素值为3
10 1 4 //第10行第1列元素值为4
10 8 2 //第2个矩阵 10行,8列,2个非零元素
2 6 1 //第2行第6列元素值为1
3 7 -3 //第3行第7列元素值为-3
H //输出格式类别

样例输出:

The transformed matrix is:
1 2 3 4 5 6 7 8 9 10
1 0 0 0 0 0 0 0 0 0 4
2 0 0 0 0 0 0 0 0 0 0
3 0 0 2 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0 0
7 0 0 3 0 0 0 0 0 0 0
8 1 0 0 0 0 0 0 0 0 0
The added matrix is:
1 2 3 4 5 6 7 8
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 1 0 0
3 0 0 2 0 0 0 0 0
4 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0
10 4 0 0 0 0 0 0 0
Can not multiply!

样例2:

100 90 5 //矩阵的行数为100,列数为90,共5个非零元素。
1 10 100 //a(1,10)=100
50 60 200 //a(50,60)=200
50 80 100 //a(50,80)=100
60 60 200 //a(60,60)=200
99 89 10 //a(99,89)=10
100 90 4 //矩阵b的行数为100,列数为90,共4个非零元素。
1 1 10 //b(1,1)=10
50 60 -200 //b(50,60)=-200
50 80 100 //b(50,80)=100
70 70 10 //b(70,70)=10
L

样例输出

The transformed matrix is:
Rows=100,Cols=90,r=5
10 1 100
60 50 200
60 60 200
80 50 100
89 99 10
The added matrix is:
Rows=100,Cols=90,r=6
1 1 10
1 10 100
50 80 200
60 60 200
70 70 10
99 89 10

Can not multiply!

样例1

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
L

样例输出:

The transformed matrix is:
Rows=90,Cols=100,r=5
10 1 100
60 50 200
60 60 200
80 50 100
89 99 10
The added matrix is:
Rows=100,Cols=90,r=6
1 1 10
1 10 100
50 80 200
60 60 200
70 70 10
99 89 10
Can not multiply!

样例2:

10 8 4
1 8 1
3 3 2
3 7 3
10 1 4
10 8 2
2 6 1
3 7 -3
H

样例输出:

The transformed matrix is:
1 2 3 4 5 6 7 8 9 10
1 0 0 0 0 0 0 0 0 0 4
2 0 0 0 0 0 0 0 0 0 0
3 0 0 2 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0 0 0
7 0 0 3 0 0 0 0 0 0 0
8 1 0 0 0 0 0 0 0 0 0
The added matrix is:
1 2 3 4 5 6 7 8
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 1 0 0
3 0 0 2 0 0 0 0 0
4 0 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0 0
6 0 0 0 0 0 0 0 0
7 0 0 0 0 0 0 0 0
8 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 0
10 4 0 0 0 0 0 0 0
Can not multiply!

AC代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
struct node
{
    int row,col,sum;
};
struct code
{
    int x,y,val;
};
bool cmp(code a,code b)
{
    if(a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
map<pair<int,int>,int> mp;
set<pair<int,int> > s;
code m1[N+5];
code m2[N+5];
code m3[N+5];
code m4[2*N+5],m5[2*N+5];
code m6[N+5];
int main()
{
    node a;
    cin>>a.row>>a.col>>a.sum;
    for(int i=1;i<=a.sum;i++) cin>>m1[i].x>>m1[i].y>>m1[i].val;
    sort(m1+1,m1+1+a.sum,cmp);
    node b;
    cin>>b.row>>b.col>>b.sum;
    for(int i=1;i<=b.sum;i++) cin>>m2[i].x>>m2[i].y>>m2[i].val;
    sort(m2+1,m2+1+b.sum,cmp);
    getchar();
    char sym;
    scanf("%c",&sym);
    //cout<<sym<<endl;
    node c;
    c.row=a.col;c.sum=a.sum;c.col=a.row;
    for(int i=1;i<=a.sum;i++)
    {
        m3[i].x=m1[i].y;
        m3[i].val=m1[i].val;
        m3[i].y=m1[i].x;
    }
    sort(m3+1,m3+1+a.sum,cmp);
    cout<<"The transformed matrix is:"<<endl;
    if(sym=='L')
    {
        printf("Rows=%d,Cols=%d,r=%d\n",c.row,c.col,c.sum);
        for(int i=1;i<=c.sum;i++) printf("%d %d %d\n",m3[i].x,m3[i].y,m3[i].val);
    }
    else
    {
        int pos=1;
        printf("    ");
        for(int i=1;i<=c.col;i++) printf("%4d",i);
        printf("\n");
        for(int i=1;i<=c.row;i++)
        {
            printf("%4d",i);
            for(int j=1;j<=c.col;j++)
            {
                if(i==m3[pos].x&&j==m3[pos].y) printf("%4d",m3[pos++].val);
                else printf("%4d",0);
            }
            printf("\n");
        }
    }
    if(a.row!=b.row||a.col!=b.col) cout<<"Can not add!"<<endl;
    else
    {
        cout<<"The added matrix is:"<<endl;
        node d;
        for(int i=1;i<=a.sum+b.sum;i++)
        {
            if(i<=a.sum) m4[i]=m1[i];
            else m4[i]=m2[i-a.sum];
        }
        sort(m4+1,m4+a.sum+b.sum+1,cmp);
        int pos=0;
        m5[++pos]=m4[1];
        /*for(int i=1;i<=a.sum+b.sum;i++)
        {
            cout<<"x=="<<m4[i].x<<" "<<"y=="<<m4[i].y<<endl;
        }*/
        for(int i=2;i<=a.sum+b.sum;i++)
        {
            if(m4[i].x==m4[i-1].x&&m4[i].y==m4[i-1].y)
            {
                m5[pos].val+=m4[i].val;
                if(m5[pos].val==0) pos--;
            }
            else m5[++pos]=m4[i];
        }
        //cout<<"pos=="<<pos<<endl;
        d.row=a.row;d.col=a.col;d.sum=pos;
        if(sym=='L')
        {
            printf("Rows=%d,Cols=%d,r=%d\n",d.row,d.col,d.sum);
            for(int i=1;i<=d.sum;i++) printf("%d %d %d\n",m5[i].x,m5[i].y,m5[i].val);
        }
        else
        {
            pos=1;
            printf("    ");
            for(int i=1;i<=d.col;i++) printf("%4d",i);
            printf("\n");
            /*for(int i=1;i<=pos;i++)
            {
                cout<<"x=="<<m5[i].x<<" "<<"y=="<<m5[i].y<<" "<<"val=="<<m5[i].val<<endl;
            }*/
            for(int i=1;i<=d.row;i++)
            {
                printf("%4d",i);
                for(int j=1;j<=d.col;j++)
                {
                    if(i==m5[pos].x&&j==m5[pos].y) printf("%4d",m5[pos++].val);
                    else printf("%4d",0);
                }
                printf("\n");
            }
        }
    }
    if(a.col!=b.row) cout<<"Can not multiply!"<<endl;
    else
    {
        cout<<"The product matrix is:"<<endl;
        node f;
        for(int i=1;i<=a.sum;i++)
        {
            for(int j=1;j<=b.sum;j++)
            {
                if(m1[i].y==m2[j].x)
                {
                    pair<int,int> ss=make_pair(m1[i].x,m2[j].y);
                    mp[ss]+=m1[i].val*m2[j].val;
                    s.insert(ss);
                }
            }
        }
        int pos=0;
        set<pair<int,int> >::iterator it;
        for(it=s.begin();it!=s.end();it++)
        {
            if(mp[*it]!=0)
            {
                pair<int,int>ss=*it;
                m6[++pos].x=ss.first;
                m6[pos].y=ss.second;
                m6[pos].val=mp[*it];
            }
        }
        f.row=a.row;
        f.col=b.col;
        f.sum=pos;
        sort(m6+1,m6+1+pos,cmp);
        if(sym=='L')
        {
            printf("Rows=%d,Cols=%d,r=%d\n",f.row,f.col,f.sum);
            for(int i=1;i<=f.sum;i++) printf("%d %d %d\n",m6[i].x,m6[i].y,m6[i].val);
        }
        else
        {
            pos=1;
            printf("    ");
            for(int i=1;i<=f.col;i++) printf("%4d",i);
            printf("\n");
            for(int i=1;i<=f.row;i++)
            {
                printf("%4d",i);
                for(int j=1;j<=f.col;j++)
                {
                    if(i==m6[pos].x&&j==m6[pos].y) printf("%4d",m6[pos++].val);
                    else printf("%4d",0);
                }
                printf("\n");
            }
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值