采用了普遍使用的三元组思路,由于看网上实现的方法感觉略复杂,便想自己用易懂的方式自己写一遍。

构建的数据结构为,结构体 sparse_node ,表示矩阵中不为0的点。结构体 sparse_mat ,内部放置 sparse_node 以及 行数 列数

#include <iostream>
#include <vector>
#include <unordered_map>
#include <map>
using namespace std;
struct sparse_node
	int i;
	int j;
	int val;
struct sparse_mat
	map<pair<int, int>, int> data;
	int row_num;
	int col_num;

关于这里为何未使用STL里的哈希表unordered_map而是使用map,这是因为我在使用unordered_map时,后续将其与vector/pair结合使用(因为想使用非零元素坐标作为键值),报错“error C2280: 'std::hash<_Kty>::hash(const std::hash<_Kty> &)': attempting to reference a deleted function”翻译过来就是“错误 C2280 “std::hash<_Kty>::hash(const std::hash<_Kty> &)”: 尝试引用已删除的函数”

上网查找原因,Stack Overflow上的解释是“ using  std::unordered_map with a  vector as a key is usually a bad idea, because of the likely high cost of implementing any kind of effective hashing function.”,就是说使用vector作为键值会导致哈希函数效率损失很多,所以官方直接把这个函数模板从unordered_map里面去掉了,使用vector/pair作为键值,最合适的数据结构是map(STL中以红黑树为底层)

稀疏矩阵乘法

于是我们就将非零元素的坐标,作为map的key,非零元素的值作为map的value。

例如,将第一个矩阵的一个元素表示为{0, 3, 4},于是(0, 3)作为键值,4作为value。假设隔壁矩阵的一个元素为{3, 1, 2},那么他们位置正好对的上,能够在最后结果矩阵里产生一个{0, 1, 8}的元素,因为4x2=8。如果另外的元素相乘也在(0, 1)位置产生了值,要将这个值与过去的8加起来才符合矩阵乘法的思想。

下面是稀疏矩阵乘法的代码示例

sparse_mat sparse_mat_product(sparse_mat mat_1, sparse_mat mat_2)
        //输出的结果稀疏矩阵
	sparse_mat result;
        //如果两矩阵维度对不上,则抛出异常
	if (mat_1.col_num != mat_2.row_num)
		throw("matrix size not match");
		result.row_num = mat_1.row_num;
		result.col_num = mat_2.col_num;
                //使用迭代器遍历第一个矩阵的非零元素
		for (auto it1 = mat_1.data.begin(); it1 != mat_1.data.end(); it1++)
                        //(*it1).first代表key,这个key是一个坐标pair,(*it1).first.first代表坐标的第一个元素,这里判断是否输入值越界
			if ((*it1).first.first > mat_1.row_num - 1 || (*it1).first.second > mat_1.col_num - 1)
				throw("index out of range");
                        //使用迭代器遍历第二个矩阵的非零元素
			for (auto it2  = mat_2.data.begin(); it2 != mat_2.data.end(); it2++)
                                //检测是否输入越界
				if ((*it2).first.first > mat_2.row_num - 1 || (*it2).first.second > mat_2.col_num - 1)
					throw("index out of range");
                                //如果第一个元素的位置和第二个元素的位置对的上,我们就将其相乘
				if ((*it1).first.second == (*it2).first.first)
                                        //确认结果矩阵中是否已经出现过该位置的值,如果没有就创建
					if (result.data.find(make_pair((*it1).first.first, (*it2).first.second)) == result.data.end())
						result.data[make_pair((*it1).first.first, (*it2).first.second)] = (*it1).second * (*it2).second;
                                        //如果已经出现过,则将其与历史值相加
						result.data[make_pair((*it1).first.first, (*it2).first.second)] += (*it1).second * (*it2).second;
	return result;
int main()
        //构建稀疏矩阵1
	sparse_mat mat1;
	vector<vector<int>> mat1_data = { {0, 3, 4}, {0, 2, 1}, {2, 2, 4 } };
	mat1.row_num = 3;
	mat1.col_num = 4;
	for (int i = 0; i <= mat1_data.size() - 1; i++)
		vector<int> tmp = mat1_data[i];
		mat1.data[make_pair(tmp[0], tmp[1])] = tmp[2];
	cout << "sparse matrix 1 :" << endl;
	cout << " size :" << mat1.row_num << " x " << mat1.col_num << endl;
	for (auto it = mat1.data.begin(); it != mat1.data.end(); it++)
		cout << "{" <<(*it).first.first << " ," << (*it).first.second << "}" << ", " << (*it).second << endl;
	cout << endl;
        //构建稀疏矩阵2
	sparse_mat mat2;
	vector<vector<int>> mat2_data = { {3, 1, 2}, {2, 1, 1}, {2, 2, 4 } };
	mat2.row_num = 4;
	mat2.col_num = 3;
	for (int i = 0; i <= mat2_data.size() - 1; i++)
		vector<int> tmp = mat2_data[i];
		mat2.data[make_pair(tmp[0], tmp[1])] = tmp[2];
	cout << "sparse matrix 2 :" << endl;
	cout << " size :" << mat2.row_num << " x " << mat2.col_num << endl;
	for (auto it = mat2.data.begin(); it != mat2.data.end(); it++)
		cout << "{" << (*it).first.first << " ," << (*it).first.second << "}" << ", " << (*it).second << endl;
	cout << endl;
        //构建结果稀疏矩阵
	sparse_mat result = sparse_mat_product(mat1, mat2);
	cout << "sparse matrix product : " << endl;
	cout << " size :" << result.row_num << " x " << result.col_num << endl;
	for (auto it = result.data.begin(); it != result.data.end(); it++)
		cout << "{" << (*it).first.first << " ," << (*it).first.second << "}" << ", " << (*it).second << endl;
	return 0;
                    题设要求构建一种数据结构,完成稀疏矩阵乘法。思路采用了普遍使用的三元组思路,由于看网上实现的方法感觉略复杂,便想自己用易懂的方式自己写一遍。构建的数据结构为,结构体sparse_node,表示矩阵中不为0的点。结构体sparse_mat,内部放置sparse_node以及行数和列数。#include &lt;iostream&gt;#include &lt;vecto...
②三元组的结构体示法:
主要算法:行逻辑链接法。前提条件是三元组按照行主索引法进行映射。同稀疏矩阵的转置操作一样,乘法操作也需要定义两个辅助的数组row_nums[i]和row_first_position[i],分别矩阵A第i行的非零元素数目和第i行第1个非零元素所在三元组中对应的索引。
对数组row_nums的赋值如下:
terms[i]矩阵A三元组第i号索引的元素,terms[i].row矩阵A这行存在元素。
对数组row_first_
那么得到的矩阵Q有三行三列,第一列中的元素有这样的关系
所以我们可以这样,在遍历到M11时,由于N11,N12,N13是在顺序中连续排列的,所以我们可以创建一个3个累加器(int QElem[4]={0}),
遍历到M11时,先算Q...
				
实现稀疏矩阵相乘C/C++ 1、问题描述:已知稀疏矩阵A(m1,n1)和B(m2,n2),求乘积C(m1,n2)。 A=|3 0 0  7|    B=|4  1|   C=|12 17|      |0 0 0 -1|         |0  0|        |0    -2|      |0 2 0  0|         |1 -1|        |0      0|
内容概要:通过带领读者感受哈的用途和魅力。了解几种解决哈冲突的方式,以及字符串哈这一特殊的哈方式。 适用人群:对于学习过基础算法并且学习过c++的学者比较友好。 可以将哈应用到什么场景? 一:安全加密,二:唯一标识,三:数据校验,六:分布式缓存,五:负载均衡等等 阅读建议:建议结合相关题型练习,手动调试相关代码,注意理解其深部含义。
数据结构课程设计之——使用C++哈实现的学生信息管理系统。 编译器选择DevC++ 或者 VS2019都可,按照要求新建文件,运行即可。 一、程序的主要功能 程序分为四个模块: 1.建立哈:有三个功能(1)插入一个学生信息;(2)删除一个学生信息;(3)修改一个学生信息。 2.查询模块:有四个功能(1)查询全部学生信息;(2)按学号查询学生信息;(3)按姓名查询学生信息;(4)按性别查询学生信息。 3.排序模块:有四个功能(1)按学号排序;(2)按年龄排序;(3)按各科成绩排序;(4)按总成绩排序。 4.统计模块:有三个功能(1)统计男女生人数;(2)统计每个人的平均成绩;(3)统计各科平均成绩。二、用户操作方法一共有七个源文件,一个头文件,六个cpp文件。将它们打开编译后即可运行。运行后按照提示操作即能实现预期的各种功能。或者双击debug图标。
Sklearn ValueError: This solver needs samples of at least 2 classes in the data, but the data qq_58457703: File "<ipython-input-48-b9389dbfc6ff>", line 5 y = data.iloc[:,8].as_matrix() SyntaxError: invalid character in identifier 博主你好,这样报错是什么意思呀 Sklearn ValueError: This solver needs samples of at least 2 classes in the data, but the data 起啥名好呢476: 为啥我输入作者的代码之后说:name 'X' is not defined Pandas 关于pandas.DataFrame.fillna 填充Nan失败的问题 Rain_Hpu: 嗯嗯,确实是少了这个参数造成的