矩阵相关操作——C++实现

注:操作较复杂,不建议写数值课设的同学借鉴

1. 定义矩阵结构体

矩阵是高等代数(线性代数)中的基本运算单位,在运算时具有一些特殊的性质。按定义来看,矩阵是由非质数(m × n)个基本元素单元组成,这些单元按一定的顺序排列,构成了一个m行n列的矩阵。
从定义中不难看出,定义矩阵的结构体需要包含三个数据成员:

  1. 行数(整型);
  2. 列数(整型);
  3. 各元素的值(根据计算精度需求进行调整).

于是定义矩阵结构体如下:

typedef struct Matrix{
   
	int row;//行数
	int col;//列数
	value *M;
	Matrix *AT;
}matrix;

其中, value是我自己定义的类型, 考虑到运算的需要, 使用long double类型:

typedef long double value;

除此之外,结构体中的结构体指针是指向该矩阵的转置,这是我为了后面编写算法方便设计的;而value* 类型的M是一个指向一个一位数组首元素地址的指针。
考虑到矩阵的大小应当是无限的,因此决定采用动态内存分配的方式给矩阵的各元素分配空间,虽然这样做矩阵的大小仍受限于内存空间的大小,但是比静态内存分配的方式在理论上更符合要求,实际场景下也能进行数据量更大的运算,比如图片处理、智能识别等。

2. 矩阵的创建

由于本人用MATLAB比较多,因此矩阵的创建方式我就照搬了MATLAB的方式:’ ’ or ‘,’ 输入某行的各元素;’;’ 换行。代码如下:

bool CreatMatrix(matrix *A) {
   
	char operation;
	int m = 0, n = 0;
	int next = 0;
	cout << "创建矩阵:" << endl;
	A->M = (value *)malloc(sizeof(value));
	cin >> *A->M;
	operation = getchar();
	while (operation != '\n') {
   
		if (operation == ' ' || operation == ',') {
   
			++next;
		}
		else if (operation == ';') {
   
			if (n == 0) {
   
				n = next;
			}
			else if (n > next) {
   
				A->M = (value *)realloc(A->M, (m + 1) * (n + 1) * sizeof(value));
				while (n != next) {
   
					++next;
					(A->M)[m * (n + 1) + next] = 0;
				}
			}
			else if (n < next) {
   
				cout << "矩阵大小有误!" << endl;
			}
			++m;
			next = 0;
		}
		else {
   
			cout << "输入有误!" << endl;
			free(A->M);
			return false;
		}		
		A->M = (value *)realloc(A->M, (m * (n + 1) + next + 1) * sizeof(value));
		cin >> (A->M)[m * (n + 1) + next];
		operation = getchar();
	}
	if (m == 0) {
   
		n = next;
	}
	else if (n > next) {
   
		A->M = (value *)realloc(A->M, (m + 1) * (n + 1) * sizeof(value));
		while (n != next) {
   
			++next;
			(A->M)[m * (n + 1) + next] = 0;
		}
	}
	++m;
	++n;
	A->row = m;
	A->col = n;
	TransMatrix(A);
	return true;
}

这里我为了偷懒,加入了一个自动补0的机制。
因为矩阵的行列数是根据输入的矩阵自动生成的,主要考虑了矩阵的合法性;而输入的合法性考虑的不是很多,若输入不合法在运算时可能会出错。
生成矩阵的情况比较多,因此代码写的有点丑。
TransMatrix是生成转置矩阵的操作,这个操作会在后面介绍。
最后这个函数是bool类型的,矩阵生成成功返回true,失败返回false。

3. 矩阵的初始化以及转置矩阵的生成

这两个算法之间其实没有太大的关系,之所以放一起只是因为它们的时间复杂度是一样的·····
初始化矩阵的代码如下,指向转置矩阵的指针初始化为空指针:

//生成 m × n 全 x 
  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
哑编码(One-Hot Encoding)是将分类变量转换为数字变量的一种常用方法。其原理是将每个分类变量的取值都转换成一个新的二元变量,取值为0或1,其中只有一个变量取值为1,其他变量都取值为0。这种方法可以避免将分类变量的取值按照大小排序,从而保留分类变量的本质特征。 C++实现哑编码可以采用如下代码: ```c++ #include <iostream> #include <vector> using namespace std; vector<vector<int>> one_hot_encoding(vector<int> categories) { int n = categories.size(); int m = *max_element(categories.begin(), categories.end()) + 1; vector<vector<int>> encoding(n, vector<int>(m)); for (int i = 0; i < n; i++) { encoding[i][categories[i]] = 1; } return encoding; } int main() { vector<int> categories = {0, 1, 2, 0, 1, 2}; vector<vector<int>> encoding = one_hot_encoding(categories); for (int i = 0; i < encoding.size(); i++) { for (int j = 0; j < encoding[i].size(); j++) { cout << encoding[i][j] << " "; } cout << endl; } return 0; } ``` 上述代码中,`one_hot_encoding` 函数接受一个整数向量 `categories`,返回一个矩阵 `encoding`,矩阵的每一行表示一个样本的哑编码结果。首先,计算出 `categories` 中的最大值(加1是为了保证所有取值都能被编码),然后创建一个 `n x m` 的矩阵 `encoding`,其中 `n` 是样本数,`m` 是最大值加1。接下来,遍历每个样本,将对应的变量编码为1,其他变量编码为0,最后返回哑编码矩阵。 运行上述代码,输出结果如下: ``` 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 1 ``` 以上即为哑编码的C++实现。下面给出一个简单的案例说明如何使用哑编码。 假设我们有一份学生信息数据表,其中包含了学生的姓名、性别和年级等分类变量。我们希望将这些变量转换为数字变量,并且使用哑编码进行处理。我们可以使用以下代码读取数据并进行哑编码: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <map> using namespace std; vector<vector<int>> one_hot_encoding(vector<int> categories); int main() { ifstream infile("students.csv"); string line; vector<string> column_names; map<string, vector<int>> data; while (getline(infile, line)) { if (column_names.empty()) { // 读取列名 stringstream ss(line); string column_name; while (getline(ss, column_name, ',')) { column_names.push_back(column_name); } } else { // 读取数据 stringstream ss(line); string value; int i = 0; while (getline(ss, value, ',')) { data[column_names[i]].push_back(stoi(value)); i++; } } } infile.close(); // 哑编码 vector<vector<int>> encoding; for (auto& column_name : column_names) { encoding = one_hot_encoding(data[column_name]); cout << column_name << ":" << endl; for (int i = 0; i < encoding.size(); i++) { for (int j = 0; j < encoding[i].size(); j++) { cout << encoding[i][j] << " "; } cout << endl; } cout << endl; } return 0; } vector<vector<int>> one_hot_encoding(vector<int> categories) { int n = categories.size(); int m = *max_element(categories.begin(), categories.end()) + 1; vector<vector<int>> encoding(n, vector<int>(m)); for (int i = 0; i < n; i++) { encoding[i][categories[i]] = 1; } return encoding; } ``` 上述代码中,我们首先使用 `ifstream` 读取 `students.csv` 文件,其中包含了学生信息数据表。然后,将数据存储在一个名为 `data` 的 `map` 中,其中键为列名,值为该列对应的数据。接下来,我们遍历每一列,使用 `one_hot_encoding` 函数对该列进行哑编码,并输出结果。 运行上述代码,输出结果如下: ``` name: 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 gender: 1 0 0 1 0 1 1 0 0 1 0 1 1 0 0 1 grade: 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 ``` 以上即为使用哑编码处理学生信息数据表的C++代码。通过将分类变量转换为数字变量,我们可以使用更多的机器学习算法来处理这些数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值