题目
利用原稀疏矩阵的三元数组
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;
}