2021秋季《数据结构》_EOJ. 1048稀疏矩阵三元组转化

题目

利用原稀疏矩阵的三元数组 a a a,求转置矩阵的三元数组 b b b,并将其规格化,即按行号递增,若行号相同则按照列号递增的顺序。
在这里插入图片描述

思路

方法1

简单排序

方法2

快速稀疏矩阵三元组转置法
由于输入按行标升序,而输出事实上是按转置后的行标升序(即转置前的列标升序),用数组num记录每一列有多少个非零元素,数组pos记录每一列的第一个非零元素是所有非零元素(按列升序)中的第几个,存入转置后的矩阵。
在提交代码过程中遇到了rte的问题,经助教指出,错因在于将大数组定义在了main函数中。经查阅资料,局部变量在(有固定大小)内分配内存空间,定义一个很大的数组可能造成栈的溢出。而定义在main外的全局变量占用(按需分配)的空间。

代码

方法1

#include<bits/stdc++.h>
using namespace std;

struct triad
{
	int row;
	int column;
	int val;
};

bool cmp(triad a, triad b)
{
	if (a.row != b.row)
		return a.row < b.row;
	return a.column < b.column;
}

int main()
{
	int m, n, c; cin >> m >> n >> c;
	triad* a = new triad[c];  // 存放转置后的三元组
	for (int i = 0; i < c; i++)
	{
		cin >> a[i].column >> a[i].row >> a[i].val;  // 以转置的形式输入
	}
	sort(a, a + c, cmp);
	for (int i = 0; i < c; i++)
	{
		cout << a[i].row << ' ' << a[i].column << ' ' << a[i].val << endl;
	}
	delete []a;
	return 0;
}

方法2

#include<bits/stdc++.h>
using namespace std;

struct Tuple
{
	int row;
	int col;
	int val;
};
Tuple a[250000];
Tuple ta[250000];
int num[1001] = { 0 };
int pos[1001] = { 0 };

int main()
{
	int m, n, c; cin >> m >> n >> c;
// 	Tuple* a = new Tuple[c];
	// 输入数据按行升序
	for (int i = 0; i < c; i++)
	{
		cin >> a[i].row >> a[i].col >> a[i].val;
	}

	//int* num = new int[n];  // 每列有多少非零元素
	//memset(num, 0, sizeof(int) * n);
	//int* pos = new int[n];  // 每列的第一个非零元素是所有非零元素中的第几个
	//memset(pos, 0, sizeof(int) * n);


	for (int i = 0; i < c; i++)
	{
		num[a[i].col]++;
	}

	pos[0] = 0;  // 第0列的第一个非零元素为所有非零元素中的第一个
	for (int i = 1; i < c; i++)
	{
		pos[i] = pos[i - 1] + num[i - 1];
	}

// 	Tuple* ta = new Tuple[c];
	// 扫描a[i]的相关数据
	for (int i = 0; i < c; i++)
	{
		int nowCol = a[i].col;  // 记录当前列
		int nowPos = pos[nowCol];  // 当前列的第一个非零元素是所有非零元素中的第nowPos个
		ta[nowPos].row = a[i].col;
		ta[nowPos].col = a[i].row;
		ta[nowPos].val = a[i].val;	
		pos[nowCol]++;  // 进入下一个非零元素
	}
	for (int i = 0; i < c; i++)
	{
		cout << ta[i].row << ' ' << ta[i].col << ' ' << ta[i].val << endl;
	}

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值