第 5 章 数组和广义表(稀疏矩阵的三元组顺序表存储实现)

news2025/6/24 9:14:58

1. 背景说明

为了节省存储空间,可以对这类矩阵进行压缩存储。所谓压缩存储是指:为多个值相同的元只分配一个存储空间,对零元不分配空间。

2. 示例代码

1)status.h

/* DataStructure 预定义常量和类型头文件 */
#include <string.h>

#ifndef STATUS_H
#define STATUS_H

#define NONE ""

#define FILE_NAME(X) strrchr(X, '\\') ? strrchr(X,'\\') + 1 : X

#define DEBUG

#define CHECK_NULL(pointer) if (!(pointer)) { \
	printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_NULL_PTR); \
	return NULL; \
}

#define CHECK_FALSE(value, ERR_CODE) if (!(value)) { \
	printf("FuncName: %-15s Line: %-5d ErrorCode: %-3d\n", __func__, __LINE__, ERR_CODE); \
	return FALSE; \
}

#ifdef DEBUG
#define CHECK_RET(ret, FORMAT, ...) if (ret != RET_OK) { \
		printf("FileName: %-20s FuncName: %-15s Line: %-5d ErrorCode: %-3d" FORMAT "\n", FILE_NAME(__FILE__), __func__, __LINE__, ret, ##__VA_ARGS__); \
		return ret; \
	}
#else
#define CHECK_RET(ret, FORMAT, ...)
#endif

#ifdef DEBUG
#define CHECK_VALUE(value, ERR_CODE, FORMAT, ...) if (value) { \
		printf("FileName: %-20s FuncName: %-15s Line: %-5d ErrorCode: %-3d" FORMAT "\n", FILE_NAME(__FILE__), __func__, __LINE__, ERR_CODE, ##__VA_ARGS__); \
		return ERR_CODE; \
	}
#else
#define CHECK_VALUE(value, ERR_CODE, FORMAT, ...)
#endif

/* 函数结果状态码 */
#define TRUE 					1			/* 返回值为真 */
#define FALSE 					0			/* 返回值为假 */
#define RET_OK 					0			/* 返回值正确 */
#define ERR_MEMORY     		   	2			/* 访问内存错 */
#define ERR_NULL_PTR   			3			/* 空指针错误 */
#define ERR_MEMORY_ALLOCATE		4			/* 内存分配错 */
#define ERR_NULL_STACK			5			/* 栈元素为空 */
#define ERR_PARA				6			/* 函数参数错 */
#define ERR_OPEN_FILE			7			/* 打开文件错 */
#define ERR_NULL_QUEUE			8			/* 队列为空错 */
#define ERR_FULL_QUEUE			9			/* 队列为满错 */
#define ERR_NOT_FOUND			10			/* 表项不存在 */
typedef int Status;							/* Status 是函数的类型,其值是函数结果状态代码,如 RET_OK 等 */
typedef int Bollean;						/* Boolean 是布尔类型,其值是 TRUE 或 FALSE */

#endif // !STATUS_H

2) tripleSparseMatrix.h

/* 稀疏矩阵的三元组顺序表存储表示头文件 */

#include "status.h"

#define MAX_SIZE 100

typedef int ElemType;

typedef struct {
	int i;
	int j;
	ElemType e;
} Triple;

typedef struct {
	Triple data[MAX_SIZE + 1];
	int rowNum;
	int colNum;
	int noneZeroNum;
} TSMatrix;

/* 创建稀疏矩阵 *sMatrix */
Status CreateSMatrix(TSMatrix *sMatrix);

/* 销毁稀疏矩阵 *sMatrix */
Status DestroySMatrix(TSMatrix *sMatrix);

/* 按照矩阵形式输出 *sMatrisx */
Status PrintSMatrix(const TSMatrix *sMatrix);

/* 由稀疏矩阵 *sMatrixA 复制得到 *sMatrixB */
Status CopySMatrix(const TSMatrix *sMatrixA, TSMatrix *sMatrixB);

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的和矩阵 *sMatrixC */
Status AddSMatrix(const TSMatrix *sMatrixA, const TSMatrix *sMatrixB, TSMatrix *sMatrixC);

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的差矩阵 *sMatrixC */
Status SubSMatrix(const TSMatrix *sMatrixA, TSMatrix *sMatrixB, TSMatrix *sMatrixC);

/* 算法 5.1,
   求稀疏矩阵 *sMatrix 的转置矩阵 *sMatrixT */
Status TransposeSMatrix(const TSMatrix *sMatrix, TSMatrix *sMatrixT);

/* 算法 5.2,
   快速求稀疏矩阵 *sMatrix 的转置矩阵 *sMatrixT */
Status FastTransposeSMatrix(const TSMatrix *sMatrix, TSMatrix *sMatrixT);

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的乘积矩阵 *sMatrixC */
Status MultSMatrix(const TSMatrix *sMatrixA, const TSMatrix *sMatrixB, TSMatrix *sMatrixC);

3) tripleSparseMatrix.c

/* 稀疏矩阵的三元组顺序表存储实现源文件 */

#include "tripleSparseMatrix.h"
#include <stdio.h>
#include <stdlib.h>

/* 创建稀疏矩阵 *sMatrix */
Status CreateSMatrix(TSMatrix *sMatrix)
{
	CHECK_VALUE(!sMatrix, ERR_NULL_PTR, NONE);
	printf("Please input the row, col, noneZeroElement of the matrix: ");
	scanf_s("%d%d%d", &(sMatrix->rowNum), &(sMatrix->colNum), &(sMatrix->noneZeroNum));
	CHECK_VALUE((sMatrix->rowNum < 1) || (sMatrix->colNum < 1) || (sMatrix->noneZeroNum < 0)
		|| (sMatrix->noneZeroNum > (sMatrix->rowNum * sMatrix->colNum)) || (sMatrix->noneZeroNum > MAX_SIZE),
		ERR_PARA, "rowNum = %d, colNum = %d, noneZeroNum = %d", sMatrix->rowNum, sMatrix->colNum, sMatrix->noneZeroNum);
	sMatrix->data[0].i = 0;
	int row, col;
	ElemType e;
	int i;
	for (i = 1; i <= sMatrix->noneZeroNum; ++i) {
		printf("Please input the row(1 ~ %d), col(1 ~ %d), and the value of %dth element: ", sMatrix->rowNum,
			sMatrix->colNum, i);
		scanf_s("%d%d%d", &row, &col, &e);
		CHECK_VALUE((row < 1) || (row > sMatrix->rowNum) || (col < 1) || (col > sMatrix->colNum) ||
			(row < sMatrix->data[i - 1].i) || ((row == sMatrix->data[i - 1].i) && (col <= sMatrix->data[i - 1].j)),
			ERR_PARA, "row = %d, rowNum = %d, col = %d, colNum = %d, lastRow = %d, lastCol = %d", row, sMatrix->rowNum,
			col, sMatrix->colNum, sMatrix->data[i - 1].i, sMatrix->data[i - 1].j);
		sMatrix->data[i].i = row;
		sMatrix->data[i].j = col;
		sMatrix->data[i].e = e;
	}

	return RET_OK;
}

/* 销毁稀疏矩阵 *sMatrix */
Status DestroySMatrix(TSMatrix *sMatrix)
{
	CHECK_VALUE(!sMatrix, ERR_NULL_PTR, NONE);
	sMatrix->rowNum = sMatrix->colNum = sMatrix->noneZeroNum = 0;

	return RET_OK;
}

/* 按照矩阵形式输出 *sMatrisx */
Status PrintSMatrix(const TSMatrix *sMatrix)
{
	CHECK_VALUE(!sMatrix, ERR_NULL_PTR, NONE);
	int count = 1;
	for (int i = 1; i <= sMatrix->rowNum; ++i) {
		for (int j = 1; j <= sMatrix->colNum; ++j) {
			if ((count <= sMatrix->noneZeroNum) && (sMatrix->data[count].i == i) && (sMatrix->data[count].j == j)) {
				printf("%-3d", sMatrix->data[count].e);
				++count;
				continue;
			}

			printf("%-3d", 0);
		}

		printf("\n");
	}

	return RET_OK;
}

/* 由稀疏矩阵 *sMatrixA 复制得到 *sMatrixB */
Status CopySMatrix(const TSMatrix *sMatrixA, TSMatrix *sMatrixB)
{
	CHECK_VALUE(!sMatrixA || !sMatrixB, ERR_NULL_PTR, "sMatrixA = %p sMatrixB = %p", sMatrixA, sMatrixB);
	errno_t ret = memcpy_s(sMatrixB, sizeof(TSMatrix), sMatrixA, sizeof(TSMatrix));
	CHECK_RET(ret, NONE);

	return RET_OK;
}

/* 返回 num1 和 num2 的大小比较结果 */
int Compare(int num1, int num2)
{
	return (num1 < num2) ? -1 : ((num1 == num2) ? 0 : 1);
}

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的和矩阵 *sMatrixC */
Status AddSMatrix(const TSMatrix *sMatrixA, const TSMatrix *sMatrixB, TSMatrix *sMatrixC)
{
	CHECK_VALUE(!sMatrixA || !sMatrixB || !sMatrixC, ERR_NULL_PTR, "sMatrixA = %p, sMatrixB = %p, sMatrixC = %p",
		sMatrixA, sMatrixB, sMatrixC);
	CHECK_VALUE((sMatrixA->rowNum != sMatrixB->rowNum) || (sMatrixA->colNum != sMatrixB->colNum), ERR_PARA,
		"sMatrixA_rowNum = %d, sMatrixB_rowNum = %d, sMatrixA_colNum = %d, sMatrixB_colNum = %d", sMatrixA->rowNum,
		sMatrixB->rowNum, sMatrixA->colNum, sMatrixB->colNum);
	sMatrixC->rowNum = sMatrixA->rowNum;
	sMatrixC->colNum = sMatrixA->colNum;
	int noneZeroNumA = 1, noneZeroNumB = 1, noneZeroNumC = 0;
	errno_t ret;
	while ((noneZeroNumA <= sMatrixA->noneZeroNum) && (noneZeroNumB <= sMatrixB->noneZeroNum)) {
		switch (Compare(sMatrixA->data[noneZeroNumA].i, sMatrixB->data[noneZeroNumB].i)) {
		case -1:
			ret = memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixA->data[noneZeroNumA++]), sizeof(Triple));
			break;
		case 0:
			switch (Compare(sMatrixA->data[noneZeroNumA].j, sMatrixB->data[noneZeroNumB].j)) {
			case -1:
				ret = memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixA->data[noneZeroNumA++]), sizeof(Triple));
				break;
			case 0:
				ret = memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixA->data[noneZeroNumA++]), sizeof(Triple));
				sMatrixC->data[noneZeroNumC].e += sMatrixB->data[noneZeroNumB++].e;
				if (sMatrixC->data[noneZeroNumC].e == 0) {
					--noneZeroNumC;
				}
				break;
			case 1:
				ret = memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixB->data[noneZeroNumB++]), sizeof(Triple));
				break;
			}

			break;
		case 1:
			ret = memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixB->data[noneZeroNumB++]), sizeof(Triple));
			break;
		}

		CHECK_RET(ret, NONE);
	}

	while (noneZeroNumA <= sMatrixA->noneZeroNum) {
		ret |= memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixA->data[noneZeroNumA++]), sizeof(Triple));
	}

	while (noneZeroNumB <= sMatrixB->noneZeroNum) {
		ret |= memcpy_s(&(sMatrixC->data[++noneZeroNumC]), sizeof(Triple), &(sMatrixB->data[noneZeroNumB++]), sizeof(Triple));
	}

	CHECK_RET(ret, NONE);
	sMatrixC->noneZeroNum = noneZeroNumC;
	CHECK_VALUE(noneZeroNumC > MAX_SIZE, ERR_PARA, "noneZeroNumC = %d", noneZeroNumC);

	return RET_OK;
}

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的差矩阵 *sMatrixC */
Status SubSMatrix(const TSMatrix *sMatrixA, TSMatrix *sMatrixB, TSMatrix *sMatrixC)
{
	CHECK_VALUE(!sMatrixA || !sMatrixB || !sMatrixC, ERR_NULL_PTR, "sMatrixA = %p, sMatrixB = %p, sMatrixC = %p",
		sMatrixA, sMatrixB, sMatrixC);
	CHECK_VALUE((sMatrixA->rowNum != sMatrixB->rowNum) || (sMatrixA->colNum != sMatrixB->colNum), ERR_PARA,
		"sMatrixA_rowNum = %d, sMatrixB_rowNum = %d, sMatrixA_colNum = %d, sMatrixB_colNum = %d", sMatrixA->rowNum,
		sMatrixB->rowNum, sMatrixA->colNum, sMatrixB->colNum);
	sMatrixC->rowNum = sMatrixA->rowNum;
	sMatrixC->colNum = sMatrixA->colNum;
	for (int i = 1; i <= sMatrixB->noneZeroNum; ++i) {
		sMatrixB->data[i].e *= -1;
	}

	Status ret = AddSMatrix(sMatrixA, sMatrixB, sMatrixC);
	CHECK_RET(ret, NONE);

	return RET_OK;
}

/* 算法 5.1,
   求稀疏矩阵 *sMatrix 的转置矩阵 *sMatrixT */
Status TransposeSMatrix(const TSMatrix *sMatrix, TSMatrix *sMatrixT)
{
	CHECK_VALUE(!sMatrix || !sMatrixT, ERR_NULL_PTR, "sMatrix = %p sMatrixT = %p", sMatrix, sMatrixT);
	sMatrixT->rowNum = sMatrix->colNum;
	sMatrixT->colNum = sMatrix->rowNum;
	sMatrixT->noneZeroNum = sMatrix->noneZeroNum;
	if (sMatrixT->noneZeroNum == 0) {
		return RET_OK;
	}

	int noneZeroNumT = 1;
	for (int col = 1; col <= sMatrix->colNum; ++col) {
		for (int i = 1; i <= sMatrix->noneZeroNum; ++i) {
			if (sMatrix->data[i].j != col) {
				continue;
			}

			sMatrixT->data[noneZeroNumT].i = sMatrix->data[i].j;
			sMatrixT->data[noneZeroNumT].j = sMatrix->data[i].i;
			sMatrixT->data[noneZeroNumT].e = sMatrix->data[i].e;
			++noneZeroNumT;
		}
	}

	return RET_OK;
}

/* 算法 5.2,
   快速求稀疏矩阵 *sMatrix 的转置矩阵 *sMatrixT */
Status FastTransposeSMatrix(const TSMatrix *sMatrix, TSMatrix *sMatrixT)
{
	CHECK_VALUE(!sMatrix || !sMatrixT, ERR_NULL_PTR, "sMatrix = %p sMatrixT = %p", sMatrix, sMatrixT);
	sMatrixT->rowNum = sMatrix->colNum;
	sMatrixT->colNum = sMatrix->rowNum;
	sMatrixT->noneZeroNum = sMatrix->noneZeroNum;
	if (sMatrixT->noneZeroNum == 0) {
		return RET_OK;
	}

	int *colNum = (int *)malloc(sizeof(int) * (unsigned long long)(sMatrix->colNum + 1));
	int *firstColNoneZero = (int *)malloc(sizeof(int) * (unsigned long long)(sMatrix->colNum + 1));
	for (int col = 1; col <= sMatrix->colNum; ++col) {
		colNum[col] = 0;
	}

	for (int i = 1; i <= sMatrix->noneZeroNum; ++i) {
		++colNum[sMatrix->data[i].j];
	}

	firstColNoneZero[1] = 1;
	for (int col = 2; col <= sMatrix->colNum; ++col) {
		firstColNoneZero[col] = firstColNoneZero[col - 1] + colNum[col - 1];
	}

	int col, order;
	for (int i = 1; i <= sMatrix->noneZeroNum; ++i) {
		col = sMatrix->data[i].j;
		order = firstColNoneZero[col];
		sMatrixT->data[order].i = sMatrix->data[i].j;
		sMatrixT->data[order].j = sMatrix->data[i].i;
		sMatrixT->data[order].e = sMatrix->data[i].e;
		++firstColNoneZero[col];
	}

	free(colNum);
	free(firstColNoneZero);

	return RET_OK;
}

/* 求稀疏矩阵 *sMatrixA 和 *sMatrixB 的乘积矩阵 *sMatrixC */
Status MultSMatrix(const TSMatrix *sMatrixA, const TSMatrix *sMatrixB, TSMatrix *sMatrixC)
{
	CHECK_VALUE(!sMatrixA || !sMatrixB || !sMatrixC, ERR_NULL_PTR, "sMatrixA = %p, sMatrixB = %p, sMatrixC = %p",
		sMatrixA, sMatrixB, sMatrixC);
	CHECK_VALUE((sMatrixA->colNum != sMatrixB->rowNum), ERR_PARA, "sMatrixA_colNum = %d, sMatrixB_rowNum = %d",
		sMatrixA->colNum, sMatrixB->rowNum);
	TSMatrix tempMatrix = { 0 };
	tempMatrix.rowNum = sMatrixB->colNum;
	tempMatrix.colNum = sMatrixA->rowNum;
	tempMatrix.noneZeroNum = 0;
	ElemType *sMatrixARow = (ElemType *)malloc(sizeof(ElemType) * (unsigned long long)(sMatrixA->rowNum + 1));
	ElemType *sMatrixBCol = (ElemType *)malloc(sizeof(ElemType) * (unsigned long long)(sMatrixB->rowNum + 1));
	CHECK_VALUE(!sMatrixARow || !sMatrixBCol, ERR_MEMORY_ALLOCATE, "sMatrixARow = %p, sMatrixBCol = %p",
		sMatrixARow, sMatrixBCol);
	for (int i = 1; i <= sMatrixB->colNum; ++i) {
		for (int j = 1; j <= sMatrixA->rowNum; ++j) {
			sMatrixARow[j] = 0;
		}

		for (int j = 1; j <= sMatrixB->rowNum; ++j) {
			sMatrixBCol[j] = 0;
		}

		for (int j = 1; j <= sMatrixB->noneZeroNum; ++j) {
			if (sMatrixB->data[j].j == i) {
				sMatrixBCol[sMatrixB->data[j].i] = sMatrixB->data[j].e;
			}
		}

		for (int j = 1; j <= sMatrixA->noneZeroNum; ++j) {
			sMatrixARow[sMatrixA->data[j].i] += sMatrixA->data[j].e * sMatrixBCol[sMatrixA->data[j].j];
		}

		for (int j = 1; j <= sMatrixA->rowNum; ++j) {
			if (sMatrixARow[j] == 0) {
				continue;
			}

			tempMatrix.data[++tempMatrix.noneZeroNum].e = sMatrixARow[j];
			tempMatrix.data[tempMatrix.noneZeroNum].i = i;
			tempMatrix.data[tempMatrix.noneZeroNum].j = j;
		}
	}

	CHECK_VALUE(tempMatrix.noneZeroNum > MAX_SIZE, ERR_PARA, "tempMatrix.noneZeroNum = %d", tempMatrix.noneZeroNum);
	Status ret = TransposeSMatrix(&tempMatrix, sMatrixC);
	CHECK_RET(ret, NONE);
	ret = DestroySMatrix(&tempMatrix);
	CHECK_RET(ret, NONE);
	free(sMatrixARow);
	free(sMatrixBCol);

	return RET_OK;
}

4) main.c

#include "tripleSparseMatrix.h"
#include <stdio.h>

int main(void)
{
	TSMatrix sMatrixA, sMatrixB, sMatrixC, sMatrixCT, sMatrixBT;
	Status ret = CreateSMatrix(&sMatrixA);
	printf("sMatrixA:\n\n");
	ret |= PrintSMatrix(&sMatrixA);
	CHECK_RET(ret, NONE);
	ret = CopySMatrix(&sMatrixA, &sMatrixB);
	printf("\nsMatrixB:\n\n");
	ret |= PrintSMatrix(&sMatrixB);
	CHECK_RET(ret, NONE);
	ret = AddSMatrix(&sMatrixA, &sMatrixB, &sMatrixC);
	printf("\nsMatrixC:\n\n");
	ret |= PrintSMatrix(&sMatrixC);
	CHECK_RET(ret, NONE);
	ret = FastTransposeSMatrix(&sMatrixC, &sMatrixCT);
	printf("\nsMatrixCT:\n\n");
	ret |= PrintSMatrix(&sMatrixCT);
	CHECK_RET(ret, NONE);

	ret = TransposeSMatrix(&sMatrixB, &sMatrixBT);
	ret |= MultSMatrix(&sMatrixA, &sMatrixBT, &sMatrixCT);
	printf("\nsMatrixA * sMatrixBT = :\n\n");
	ret |= PrintSMatrix(&sMatrixCT);
	CHECK_RET(ret, NONE);

	ret |= DestroySMatrix(&sMatrixA);
	ret |= DestroySMatrix(&sMatrixC);
	ret |= DestroySMatrix(&sMatrixCT);
	CHECK_RET(ret, NONE);

	return 0;
}

3. 输出结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1086120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Adobe Premiere Elements 2024:轻松创建精彩视频的简化版专业工具

随着视频内容的日益流行和人们对高质量多媒体内容的需求不断增长&#xff0c;Adobe Premiere Elements 2024 成为了许多非专业视频编辑者首选的工具。这款软件究竟有何特别之处&#xff1f;本文将详细介绍 Adobe Premiere Elements 2024&#xff0c;并为您揭示它的简化版专业功…

Java集合(四) --- Map

好潦草的一篇文章&#xff0c;不想学习想摆烂了又 &#xff0c;凑合看 文章目录 一、Map的实现类的结构二、Map结构的理解三、HashMap的底层实现原理? 以jdk7的说明:四、Map中定义的方法五、总结&#xff1a;常用方法六、代码 提示&#xff1a;以下是本篇文章正文内容&#xf…

企业活动目录管理利弊

凡事都有利和弊&#xff0c;那么如何解决企业活动目录管理中的各种弊端呢&#xff1f; 首先Windows环境是目前企业使用率最高的网络环境&#xff0c;作为windows最核心的组件&#xff0c;活动目录&#xff08;AD域&#xff09;自然被很多企业使用&#xff0c;其主要作用就是更…

goland 旧版本使用1.19环境

C:\Go\src\runtime\internal\sys\zversion.go // Code generated by go tool dist; DO NOT EDIT.package sysconst StackGuardMultiplierDefault 1const TheVersion go1.19引入其他包的标识符 package mainimport ("fmt""gotest/test")func main() {f…

扫描器(xray和bp联动)

文章目录 分类主动扫描和被动扫描bp与xray联动 分类 扫描器分为对web的扫描器和对主机的扫描器 主动扫描和被动扫描 主动扫描&#xff1a; 输入某个URL&#xff0c;然后由扫描器中的爬虫模块爬取所有链接&#xff0c;对GET、POST等请求进行参数变形和污染&#xff0c;进行重放测…

利用Cpolar内网穿透+HadSky技术构建您的私密高效论坛网站

文章目录 前言1. 网站搭建1.1 网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09;2.4 公网访问测试 总结 前言 经过多年的基础…

YOLOv7改进:CoordAttention新型的轻量级自注意力机制| CVPR2021

💡💡💡本文独家改进:CoordAttention是一种新型的自注意力机制,可以加入到YOLOV7中不同位置验证涨点可行性 CoordAttention| 亲测在多个数据集能够实现大幅涨点 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨✨✨前沿最新计算机顶会复现 🚀�…

docker compose 部署ELK 8.X及监控

1. 前置环境 安装docker 安装docker-compose 相关版本&#xff1a; ES&#xff1a;8.5.0 kibana&#xff1a;8.5.0 logstash&#xff1a;8.5.0 2. docker-compose yaml文件 # 在指定路径创建配置文件 vim docker-compose-es-kibana-logstash.yamlversion: "3"…

【知网检索征稿】第三届社会发展与媒体传播国际学术会议(SDMC 2023)

第三届社会发展与媒体传播国际学术会议&#xff08;SDMC 2023&#xff09; 2023 3rd International Conference on Social Development and Media Communication 第三届社会发展与媒体传播国际学术会议 (SDMC 2023)将于2023年11月03-05日在中国杭州召开。会议主题主要围绕社会…

【独家】网络电视盒子哪个品牌好?实测总结目前性能最好的电视盒子

电视盒子可谓是居家必备&#xff0c;尤其是对老人小孩来说使用频率非常高&#xff0c;我做数码测评这几年陆陆续续已经测评过30多款电视盒子了&#xff0c;今天盘一盘目前性能最好的电视盒子&#xff0c;给不懂如何挑选电视盒子的朋友们做个参考。 NO.1 泰捷WEBOX WE40S电视盒子…

让数据“动”起来:Python动态图表制作!

在读技术博客的过程中&#xff0c;我们会发现那些能够把知识、成果讲透的博主很多都会做动态图表。他们的图是怎么做的&#xff1f;难度大吗&#xff1f;这篇文章就介绍了 Python 中一种简单的动态图表制作方法。 数据暴增的年代&#xff0c;数据科学家、分析师在被要求对数据有…

域渗透04-漏洞(CVE-2020-1472)

Netlogon协议&#xff1a; 想了解CVE-2020-1472&#xff0c;我们首先必须要了解Netlogon协议是什么&#xff1a; Netlogon 远程协议是 Windows 域控制器上可用的 RPC 接口。它用于与用户和计算机身份验证相关的各种任务&#xff0c;最常见的是方便用户使用 NTLM 协议登录到服务…

计算机毕业设计选什么题目好?springboot 健身房管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Tmux教学【有图有代码】

Tmux教学【有图有代码】 0、前言1、Tmux基本概念1.1 安装 2、Tmux使用2.1 session操作2.2 window操作2.3 pane操作2.4 其他操作 3、日常中Tmux的工作流 0、前言 想必同学们在跑代码时也许会存在这样一个问题&#xff1a; 本地在连接远程服务器跑代码的时候&#xff0c;本地ssh窗…

一分钟!图片生成32种动画;Adobe绘画工具大升级;复盘Kaggle首场LLM比赛;VR科普万字长文 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; Adobe Firefly 大升级&#xff01;图像高清、操作便利&#xff0c;体验感拉满 https://firefly.adobe.com Adobe Firefly 升级了&…

钉钉智慧校园小程序如何开发,你知道么!

随着科技的不断发展&#xff0c;数字化已经成为了现代校园发展的重要趋势。在这个背景下&#xff0c;数字智慧校园小程序应运而生&#xff0c;为校园用户提供了更加便捷、高效的生活和学习体验。本文将围绕钉钉数字智慧校园小程序搭建方案进行创作&#xff0c;主要内容包括背景…

在ThingsBoard中,使用部件库自定义RPC下发内容

众所周知,在ThingsBoard中可以对设备进行RPC指令的下发,但有一个限制,必须符合以下的格式 {method:get,payload: {a: a} }所发送的内容必须包含method 与payload。两个字段。 有关RPC的API 可以查询这个链接 https://thingsboard.io/docs/user-guide/rpc/ 但是有朋友要求…

springboot企业客户信息反馈平台springboot39

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

多输入多输出 | MATLAB实现CNN-GRU-Attention卷积神经网络-门控循环单元结合SE注意力机制的多输入多输出预测

多输入多输出 | MATLAB实现CNN-GRU-Attention卷积神经网络-门控循环单元结合SE注意力机制的多输入多输出预测 目录 多输入多输出 | MATLAB实现CNN-GRU-Attention卷积神经网络-门控循环单元结合SE注意力机制的多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果…

Linux C文件操作

文章目录 文件操作函数文件系统调用系统调用与标准函数c的调用的区别文件的读取位置标准c函数系统调用空洞文件 文件的内存映射操作文件目录 linux下的文件操作包括两种&#xff0c;一种是使用C函数&#xff0c;一种是使用系统调用。 gcc 常用来实现c程序的编译gcc filename.c …