【数据结构】顺序表实现通讯录

前言
在上一节中我们实现了顺序表,现在我们将使用顺序表完成通讯录的实现。(注:本人水平有限,“小屎山”有些许bug,代码冗余且语无伦次,望谅解!😅)
文章目录
- 一、数据结构设计
- 二、初始化和内存管理
- 初始化
- 动态扩容
- 三、基础功能实现:增删改查
- 添加联系人
- 删除联系人
- 修改联系人
- 查找联系人
- 显示通讯录
- 四、文件操作
- 保存至文件
- 从文件读取
- 五、所有代码
- contact.h
- contact.c
- main.c
一、数据结构设计
首先,定义一个结构体Contact来存储单个联系人的信息,包括姓名、性别、年龄和手机号。
typedef struct Contact {char name[NAME_MAX]; //姓名char sex[SEX_MAX]; //性别int age; //年龄char phone[PHONE_MAX];//手机号
}Contact;
然后,定义一个结构体SeqList(序列表)用于存储所有联系人信息。该结构体包含一个指向Contact结构体数组的指针data,以及两个整数,size表示当前有效数据个数,capacity表示当前数组容量。
typedef struct SeqList {Contact* data; //通讯录信息int size; //有效数据个数int capacity; //通讯录总容量
}ConList;
二、初始化和内存管理
初始化
在程序开始之前,我们需要进行初始化操作,即为SeqList中的data分配内存,并设置初始值。
int ContactInit(ConList* list) { assert(list);Contact* tmp = (Contact*)malloc(sizeof(Contact));if (tmp==NULL) {printf("内存分配失败\n");return -1;}list->data = tmp;list->size = 0;list->capacity = 1;return 0;
}
动态扩容
如果SeqList中的data数组已满,我们需要进行扩容。
int resizeConList(ConList* list) {assert(list);int newCapacity = list->capacity * 2;Contact* newData = (Contact*)realloc(list->data, sizeof(Contact) * newCapacity);if (newData == NULL) {printf("内存分配失败\n");return -1;}list->data = newData;list->capacity = newCapacity;return 0;
}
三、基础功能实现:增删改查
添加联系人
添加联系人时,需要先检查是否有足够的空间,如果没有则扩容。然后,通过标准输入获取联系人信息。
int ContactAdd(ConList* list) {assert(list);char sign = 'N';do {if (list->size >= list->capacity) {int ret = resizeConList(list);if (ret == -1) {printf("通讯录扩大失败\n");return -1;}}printf("请输入姓名:>");scanf(" %20s", list->data[list->size].name); // 限制输入长度printf("请输入性别:>");scanf(" %7s", list->data[list->size].sex); // 限制输入长度printf("请输入年龄:>");if (scanf("%d", &(list->data[list->size].age)) != 1) {printf("无效的年龄输入\n");return -1;}printf("请输入手机号:>");scanf(" %20s", list->data[list->size].phone); // 限制输入长度list->size++;ContactShow(list);printf("Y 继续添加 N 结束 请输入:>");scanf(" %c", &sign); // 注意空格,用于吸收前一个输入后可能残留的换行符printf("***********************************\n");} while (sign == 'Y' || sign == 'y');return 0;
}
删除联系人
删除联系人时,需要输入要删除的联系人的序号。
int ContactDel(ConList* list) {assert(list);ContactShow(list);int input = 0;//要删除联系人序号char sign = 0;do {printf("\n");printf("选择要删除的联系人的序号:>");scanf("%d", &input);for (int i = input; i < list->size; i++) {list->data[i - 1] = list->data[i];}list->size--;ContactShow(list);printf("Y 继续删除 N 结束 请输入:>");scanf(" %c", &sign);} while (sign=='Y'||sign=='y');return 0;
}
修改联系人
修改联系人与添加联系人类似,但需要先定位到要修改的联系人。
int ContactModify(ConList* list) {assert(list);ContactShow(list);int input = 0;//要修改的联系人序号char sign = 0;do {printf("\n");printf("选择要修改的联系人序号:>");scanf("%d", &input);//联系人信息修改printf("请输入姓名:>");scanf(" %20s", list->data[input-1].name); printf("请输入性别:>");scanf(" %7s", list->data[input - 1].sex);printf("请输入年龄:>");if (scanf("%d", &(list->data[input - 1].age)) != 1) {printf("无效的年龄输入\n");return -1;}printf("请输入手机号:>");scanf(" %20s", list->data[input - 1].phone); ContactShow(list);printf("Y 继续修改 N 结束 请输入:>");scanf(" %c",&sign);} while (sign == 'Y' || sign == 'y');return 0;
}
查找联系人
可以通过姓名或手机号进行查找。
int ContactFind(ConList* list) {assert(list);int input = 0;char keyword[21] = {0};//联系人关键字int sign = 0;//联系人是否找到判断do {sign = 0;printf("选择查找联系人方式 1 姓名查找 2 手机号查找 0 退出查找:>");scanf("%d", &input);if (!input) return 0;//退出查找printf("请输入查找关键字:>");scanf(" %20s", keyword); // 限制输入长度switch (input) {case 1: // 按姓名查找for (int i = 0; i < list->size; i++) {if (strcmp(list->data[i].name, keyword) == 0) {printf("找到联系人:%d\n", i + 1);sign = 1;break;}}break;case 2: // 按手机号查找for (int i = 0; i < list->size; i++) {if (strcmp(list->data[i].phone, keyword) == 0) {printf("找到联系人的序号:%d\n", i + 1);sign = 1;break;}}break;default:printf("无效的选项\n");break;}} while (input);if (!sign) {printf("未找到联系人\n");}return 0;
}
显示通讯录
int ContactShow(ConList* list) {assert(list);int count = 1;//序号printf("--------------------------------------------------------------\n");printf("|序号| 姓名 | 性别 |年龄| 手机号 |\n");while (count <= list->size) {printf("--------------------------------------------------------------\n");printf("|%-4d|%-20s|%-8s|%-4d|%-20s|\n",count,list->data[count - 1].name, list->data[count - 1].sex, list->data[count - 1].age,list->data[count - 1].phone);count++;}printf("--------------------------------------------------------------\n");return 0;
}
四、文件操作
保存至文件
使用二进制模式将所有联系人信息保存到文件。
int ContactSave(ConList* list) {assert(list);FILE* file = fopen("contact.dat", "wb");if (file == NULL) {printf("无法创建或打开文件\n");return -1;}// 写入通讯录的大小(元素数量)fwrite(&(list->size), sizeof(int), 1, file);// 写入通讯录的数据fwrite(list->data, sizeof(Contact), list->size, file);fclose(file);file=NULL;return 0;
}
从文件读取
与保存操作相反,从文件中读取所有联系人信息。
int ContactLoad(ConList* list) {assert(list);FILE* file = fopen("contact.dat", "rb+");if (file == NULL) {printf("无法打开文件\n");return -1;}// 读取通讯录的大小(元素数量)fread(&(list->size), sizeof(int), 1, file);// 根据读取到的大小动态分配内存if (list->size) {Contact* tmp = (Contact*)realloc(list->data, sizeof(Contact) * list->size);if (tmp == NULL) {printf("内存分配失败\n");fclose(file);return -1;}list->data = tmp;// 读取通讯录的数据fread(list->data, sizeof(Contact), list->size, file);list->capacity = list->size; // 在这个简单示例中,将容量设置为大小}fclose(file);return 0;
}
五、所有代码
contact.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>#define NAME_MAX 20
#define SEX_MAX 7
#define PHONE_MAX 20typedef struct Contact {char name[NAME_MAX]; //姓名char sex[SEX_MAX]; //性别int age; //年龄char phone[PHONE_MAX];//手机号
}Contact;typedef struct SeqList {Contact* data; //通讯录信息int size; //有效数据个数int capacity; //通讯录总容量
}ConList;//添加联系人
int ContactAdd(ConList* list);
//删除联系人
int ContactDel(ConList* list);
//修改联系人
int ContactModify(ConList* list);
//查找指定联系人
int ContactFind(ConList* list);//通讯录的初始化
int ContactInit(ConList* list);
//通讯录扩容
int resizeConList(ConList* list);
//通讯录销毁
void ContactDestroy(ConList* list);
//查看通讯录
int ContactShow(ConList* list);//检测contact.dat存不存在,如果不存在就创建一个
int checkAndCreateFile(const char* filename);
//保存通讯录到文件
int ContactSave(ConList* list);
//从文件中读取通讯录
int ContactLoad(ConList* list);
contact.c
#include"contact.h"int ContactInit(ConList* list) { assert(list);Contact* tmp = (Contact*)malloc(sizeof(Contact));if (tmp==NULL) {printf("内存分配失败\n");return -1;}list->data = tmp;list->size = 0;list->capacity = 1;return 0;
}int resizeConList(ConList* list) {assert(list);int newCapacity = list->capacity * 2;Contact* newData = (Contact*)realloc(list->data, sizeof(Contact) * newCapacity);//通常扩容选择1.5倍或者2倍进行扩容if (newData == NULL) {printf("内存分配失败\n");return -1;}list->data = newData;list->capacity = newCapacity;return 0;
}int ContactAdd(ConList* list) {assert(list);char sign = 'N';do {if (list->size >= list->capacity) {int ret = resizeConList(list);if (ret == -1) {printf("通讯录扩大失败\n");return -1;}}printf("请输入姓名:>");scanf(" %20s", list->data[list->size].name); // 限制输入长度printf("请输入性别:>");scanf(" %7s", list->data[list->size].sex); // 限制输入长度printf("请输入年龄:>");if (scanf("%d", &(list->data[list->size].age)) != 1) {printf("无效的年龄输入\n");return -1;}printf("请输入手机号:>");scanf(" %20s", list->data[list->size].phone); // 限制输入长度list->size++;ContactShow(list);printf("Y 继续添加 N 结束 请输入:>");scanf(" %c", &sign); // 注意空格,用于吸收前一个输入后可能残留的换行符printf("***********************************\n");} while (sign == 'Y' || sign == 'y');return 0;
}int ContactShow(ConList* list) {assert(list);int count = 1;//序号printf("--------------------------------------------------------------\n");printf("|序号| 姓名 | 性别 |年龄| 手机号 |\n");while (count <= list->size) {printf("--------------------------------------------------------------\n");printf("|%-4d|%-20s|%-8s|%-4d|%-20s|\n",count,list->data[count - 1].name, list->data[count - 1].sex, list->data[count - 1].age,list->data[count - 1].phone);count++;}printf("--------------------------------------------------------------\n");return 0;
}int ContactDel(ConList* list) {assert(list);ContactShow(list);int input = 0;//要删除联系人序号char sign = 0;do {printf("\n");printf("选择要删除的联系人的序号:>");scanf("%d", &input);for (int i = input; i < list->size; i++) {list->data[i - 1] = list->data[i];}list->size--;ContactShow(list);printf("Y 继续删除 N 结束 请输入:>");scanf(" %c", &sign);} while (sign=='Y'||sign=='y');return 0;
}int ContactModify(ConList* list) {assert(list);ContactShow(list);int input = 0;//要修改的联系人序号char sign = 0;do {printf("\n");printf("选择要修改的联系人序号:>");scanf("%d", &input);//联系人信息修改printf("请输入姓名:>");scanf(" %20s", list->data[input-1].name); printf("请输入性别:>");scanf(" %7s", list->data[input - 1].sex);printf("请输入年龄:>");if (scanf("%d", &(list->data[input - 1].age)) != 1) {printf("无效的年龄输入\n");return -1;}printf("请输入手机号:>");scanf(" %20s", list->data[input - 1].phone); ContactShow(list);printf("Y 继续修改 N 结束 请输入:>");scanf(" %c",&sign);} while (sign == 'Y' || sign == 'y');return 0;
}int ContactFind(ConList* list) {assert(list);int input = 0;char keyword[21] = {0};//联系人关键字int sign = 0;//联系人是否找到判断do {sign = 0;printf("选择查找联系人方式 1 姓名查找 2 手机号查找 0 退出查找:>");scanf("%d", &input);if (!input) return 0;//退出查找printf("请输入查找关键字:>");scanf(" %20s", keyword); // 限制输入长度switch (input) {case 1: // 按姓名查找for (int i = 0; i < list->size; i++) {if (strcmp(list->data[i].name, keyword) == 0) {printf("找到联系人:%d\n", i + 1);sign = 1;break;}}break;case 2: // 按手机号查找for (int i = 0; i < list->size; i++) {if (strcmp(list->data[i].phone, keyword) == 0) {printf("找到联系人的序号:%d\n", i + 1);sign = 1;break;}}break;default:printf("无效的选项\n");break;}} while (input);if (!sign) {printf("未找到联系人\n");}return 0;
}void ContactDestroy(ConList* list) {assert(list);// 释放动态分配的数组内存if (list->data != NULL) {free(list->data);}// 将各成员变量设置为初始状态list->data = NULL;list->size = 0;list->capacity = 0;
}int ContactSave(ConList* list) {assert(list);FILE* file = fopen("contact.dat", "wb");if (file == NULL) {printf("无法创建或打开文件\n");return -1;}// 写入通讯录的大小(元素数量)fwrite(&(list->size), sizeof(int), 1, file);// 写入通讯录的数据fwrite(list->data, sizeof(Contact), list->size, file);fclose(file);file=NULL;return 0;
}int ContactLoad(ConList* list) {assert(list);FILE* file = fopen("contact.dat", "rb+");if (file == NULL) {printf("无法打开文件\n");return -1;}// 读取通讯录的大小(元素数量)fread(&(list->size), sizeof(int), 1, file);// 根据读取到的大小动态分配内存if (list->size) {Contact* tmp = (Contact*)realloc(list->data, sizeof(Contact) * list->size);if (tmp == NULL) {printf("内存分配失败\n");fclose(file);return -1;}list->data = tmp;// 读取通讯录的数据fread(list->data, sizeof(Contact), list->size, file);list->capacity = list->size; // 在这个简单示例中,将容量设置为大小}fclose(file);return 0;
}int checkAndCreateFile(const char* filename) {FILE* file;// 尝试以读模式打开文件file = fopen(filename, "r");// 检查文件是否已经存在if (file != NULL) {// 文件存在,关闭文件fclose(file);printf("contact.dat存在\n");return 0; // 返回0表示文件已存在,无需创建}else {// 文件不存在,以写模式创建一个新文件file = fopen(filename, "w");if (file != NULL) {fclose(file);printf("文件创建成功\n");return 1; // 返回1表示文件成功创建}else {// 文件创建失败,可能是因为权限或磁盘空间不足等原因printf("文件创建失败\n");return -1; // 返回-1表示文件创建失败}}
}
main.c
#include"contact.h"void menu() {printf("-------------------------------------\n");printf("-----1 添加联系人 2 删除联系人-----\n");printf("-----3 修改联系人 4 查找联系人-----\n");printf("-------------0 退出通讯录------------\n");printf("-------------------------------------\n");}int main() {ConList list;ContactInit(&list);//通讯录初始化checkAndCreateFile("contact.dat");//检测contact.dat存不存在,如果不存在就创建一个//从文件中读取通讯录ContactLoad(&list);int input = 0;do {menu();printf("\n");printf("选择操作:>");scanf("%d",&input);switch(input){case 1:ContactAdd(&list);break;case 2:ContactDel(&list);break;case 3:ContactModify(&list);break;case 4:ContactFind(&list);break;default:break;}} while (input);ContactSave(&list);//保存通讯录到文件ContactDestroy(&list);//通讯录销毁return 0;
}

如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。
相关文章:
【数据结构】顺序表实现通讯录
前言 在上一节中我们实现了顺序表,现在我们将使用顺序表完成通讯录的实现。(注:本人水平有限,“小屎山”有些许bug,代码冗余且语无伦次,望谅解!😅) 文章目录 一、数据结构…...
JMeter 随机数生成器简介:使用 Random 和 UUID 算法
在压力测试中,经常需要生成随机值来模拟用户行为。JMeter 提供了多种方式来生成随机值,本文来具体介绍一下。 随机数函数 JMeter 提供了多个用于生成随机数的函数,其中最常用的是 __Random 函数。该函数可以生成一个指定范围内的随机整数或…...
vue3 更换 elemnt-ui / element-plus 版本npm命令
1. 安装 / 更换 element-ui 版本 [ 在 后面指定想要安装的版本 ] //卸载当前版本 npm uninstall element-ui //安装指定版本 npm i element-ui2.4.8 -S --legacy-peer-deps 2. 安装 / 更换 element-plus 版本 [ 在 后面指定想要安装的版本 ] npm install element-plus2.3…...
react.js 手写响应式 reactive
Redux 太繁琐,Mbox 很酷但我们可能没必要引入新的包,那就让我们亲自在 react.js 中通过代理实现一套钩子来达到类似 vue 的响应式状态: 实现 reactive hooks 代理类声明 代理状态的类应当提供可访问的状态,和订阅变化的接口。 …...
代码随想录打卡第四十六天|完全背包 ● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ
完全背包理论 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。 完全背包和01背包问题唯一…...
【BP-Adaboost预测】基于BP神经网络的Adaboost的单维时间序列预测研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Origami Studio for Mac:塑造未来,掌握原型设计之巅
在当今高度竞争的设计领域,原型设计的重要性不言而喻。它不仅是沟通想法,也是测试和改进设计的关键环节。而现在,一款强大的原型设计工具——Origami Studio for Mac,正在席卷设计界,以其独特的功能和卓越的性能&#…...
UML类图中各箭头表示总结
UML类图中各箭头表示总结 1、泛化2、实现3、依赖4、关联5、聚合6、组合 在UML类图中,箭头关系是用来表示类之间的关系的。箭头关系的种类有以下几种: 1、泛化 泛化:表示类之间的继承关系。箭头从子类指向父类。箭头:实线空心三角…...
神经网络量化----为了部署而特别设计
引言:一般神经网络量化有两个目的: 为了加速,在某些平台上浮点数计算比较耗费时间,替换为整形可以加快运算为了部署,某些平台上只支持整形运算,比如在芯片中如果是第1个目的,则使用常规的量化手段就可以满足,将浮点数运算变成整形运算+较少的浮点运算 但是如果是第2个目…...
代码随想录算法训练营Day60|单调栈01
代码随想录算法训练营Day60|单调栈01 文章目录 代码随想录算法训练营Day60|单调栈01一、739. 每日温度二、496.下一个更大元素 I 一、739. 每日温度 class Solution {public int[] dailyTemperatures(int[] temperatures) {//单调栈int lenstemperatures.length;int result[]n…...
openMP学习笔记 -编程模型
OpenMP模型 gcc编译openmp指令:gcc test.cpp -o test -fopenmp 定积分计算 函数面积 给定一个定积分,计算其面积: ∫ 0 1 4.0 ( 1 x 2 ) d x \int^{1}_{0}{\frac{4.0}{(1x^2)}dx} ∫01(1x2)4.0dx omp 概念 并行区域 并行区域用于…...
【Hive SQL 每日一题】环比增长率、环比增长率、复合增长率
文章目录 环比增长率同比增长率复合增长率测试数据需求说明需求实现 环比增长率 环比增长率是指两个相邻时段之间某种指标的增长率。通常来说,环比增长率是比较两个连续时间段内某项数据的增长量大小的百分比。 环比增长率反映了两个相邻时间段内某种经济指标的变…...
Java设计模式之外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。外观模式通过隐藏子系统的复杂性,简化了客户端与子系统之间的交互,提供了一个更简单、更直观的接口。…...
【大疆智图】大疆智图(DJI Terra 3.0.0)安装及使用教程
大疆智图是一款以二维正射影像与三维模型重建为主的软件,同时提供二维多光谱重建、激光雷达点云处理、精细化巡检等功能。它能够将无人机采集的数据可视化,实时生成高精度、高质量三维模型,满足事故现场、工程监测、电力巡线等场景的展示与精确测量需求。 文章目录 1. 安装D…...
腾讯地图基本使用(撒点位,点位点击,弹框等...功能) 搭配Vue3
腾讯地图的基础注册账号 展示地图等基础功能在专栏的上一篇内容 大家有兴趣可以去看一看 今天说的是腾讯地图的在稍微一点的基础操作 话不多说 直接上代码 var marker ref(null) var map var center ref(null) // 地图初始化 const initMap () > {//定义地图中心点坐标…...
散列表:Word文档中的单词拼写检查功能是如何实现的?
文章来源于极客时间前google工程师−王争专栏。 一旦我们在Word里输入一个错误的英文单词,它就会用标红的方式提示“编写错误”。Word的这个单词拼写检查功能,虽然很小但却非常实用。这个功能是如何实现的? 散列别(Hash Table&am…...
智慧公厕蜕变多功能城市智慧驿站公厕的创新
随着城市发展的不断推进,对公共设施的便利性和智能化要求也日益提高。为满足市民对高品质、便捷、舒适的公共厕所的需求,智慧公厕行业的领航厂家广州中期科技有限公司,全新推出了一体化智慧公厕驿站。凭借着“高科技碳中和物联网创意设计新经…...
R语言清洗与处理数据常用代码段
去掉数据框df的某一列: # 删除不必要的变量 data$unnecessary_var <- NULL 选择需要的列进行读入数据框: # 选择需要的列 selected_cols <- c("col1", "col2", "col3") data <- fread("data.csv", s…...
centos 7.9 安装python 3.10的tls问题,
本地开发升级成了py3.10.6,服务器测试时安装py3.10.4 发现无法正常使用pip3 pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. 印象中py3的高版本依赖高版本的openssl,centos 7下默认的openssl为1.0.x, 问题很简…...
pytorch,tf维度理解RNN
input_t input_t.squeeze(1) 这行代码用于从 input_t 中去除尺寸为1的维度。在深度学习中,经常会出现具有额外尺寸为1的维度,这些维度通常是为了匹配模型的期望输入维度而添加的。 在这里,input_t可能具有形状 (batch_size, 1, feature_dim…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
