当前位置: 首页 > news >正文

啊哈 算法读书笔记 第 2 章 栈、队列、链表

第 2 章 栈、队列、链表

目录

第 2 章 栈、队列、链表

队列:

解密回文——栈

纸牌游戏:

链表

模拟链表 

队列:

首先将第 1 个数删除,紧接着将第 2 个数放到这串数的末尾,再将第 3 个数删除并将第 4 个数放到这串数的末尾,再将第 5 个数删除……直到剩下最后一个数,将最后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一起就是小哈的 号码啦。现在你来帮帮小哼吧。小哈给小哼加密过的一串数是“6 3 1 7 5 8 9 2 4”。

要去用程序来解决的话: 

#include <stdio.h> 
int main() 
{ int q[102]={0,6,3,1,7,5,8,9,2,4},head,tail; int i; //初始化队列head=1; tail=10; //队列中已经有9个元素了,tail指向队尾的后一个位置 while(head<tail) //当队列不为空的时候执行循环{ //打印队首并将队首出队printf("%d ",q[head]); head++; //先将新队首的数添加到队尾q[tail]=q[head]; tail++; //再将队首出队head++; } getchar();getchar(); return 0; 
}

队列的概念:

队列是一种特殊的线性结构,它只允许在队列的首部(head)进行删除操作,这称为“出队”,而在队列的尾部(tail)进行插入操作,这称为“入队”。当队列中没有元素时(即 head==tail),称为空队列。
队列将是我们今后学习广度优先搜索以及队列优化的 Bellman-Ford 最短路算法的核心
数据结构。所以现在将队列的三个基本元素(一个数组,两个变量)封装为一个结构体类型,
如下。
struct queue 
{ int data[100];//队列的主体,用来存储内容int head;//队首int tail;//队尾
};
可以这么理解:我们定义了一个新的数据类型,这个新类型非常强大,用这个新类型定义出的每一个变量可以同时存储一个整型数组和两个整数。

 使用结构体来实现的队列操作

#include <stdio.h> 
struct queue 
{ int data[100];//队列的主体,用来存储内容int head;//队首int tail;//队尾
}; 
int main() 
{ struct queue q; int i; //初始化队列q.head=1; q.tail=1; for(i=1;i<=9;i++) { //依次向队列插入9个数scanf("%d",&q.data[q.tail]); q.tail++; } while(q.head<q.tail) //当队列不为空的时候执行循环{ //打印队首并将队首出队printf("%d ",q.data[q.head]); q.head++; //先将新队首的数添加到队尾q.data[q.tail]=q.data[q.head]; q.tail++; //再将队首出队q.head++; } getchar();getchar(); return 0; 
}

解密回文——栈

 原书中对栈的说明:

栈究竟有哪些作用呢?我们来看一个例子。“xyzyx”是一个回文字符串,所谓回文字符
串就是指正读反读均相同的字符序列,如“aha”和“ahaha”均是回
文,但“ahah”不是回文。通过栈这个数据结构我们将很容易判断一个字符串是否为回文。
首先我们需要读取这行字符串,并求出这个字符串的长度。
char a[101];
int len;
gets(a);
len=strlen(a);
如果一个字符串是回文的话,那么它必须是中间对称的,我们需要求中点,即:
mid=len/2-1;
接下来就轮到栈出场了。
我们先将 mid 之前的字符全部入栈。因为这里的栈是用来存储字符的,所以这里用来实
现栈的数组类型是字符数组即 char s[101];,初始化栈很简单,top=0;就可以了。入栈的操作
top++; s[top]=x; (假设需要入栈的字符暂存在字符变量x中),其实可以简写为s[++top]=x;
现在我们就来将 mid 之前的字符依次全部入栈。
for(i=0;i<=mid;i++)
{
s[++top]=a[i];
}
接下来进入判断回文的关键步骤。将当前栈中的字符依次出栈,看看是否能与 mid 之后
的字符一一匹配,如果都能匹配则说明这个字符串是回文字符串,否则这个字符串就不是回
文字符串。
for(i=mid+1;i<=len-1;i++)
{
if (a[i]!=s[top])
{
break;
}
top--;
}
if(top==0)
printf("YES");
else
printf("NO");
最后如果 top 的值为 0,就说明栈内所有的字符都被一一匹配了,那么这个字符串就是
回文字符串。完整的代码如下。
#include <stdio.h>
#include <string.h>
int main()
{
char a[101],s[101];
int i,len,mid,next,top;gets(a); //读入一行字符串
len=strlen(a); //求字符串的长度
mid=len/2-1; //求字符串的中点top=0;//栈的初始化
//将mid前的字符依次入栈
for(i=0;i<=mid;i++)
s[++top]=a[i];//判断字符串的长度是奇数还是偶数,并找出需要进行字符匹配的起始下标
if(len%2==0)
next=mid+1;
else
next=mid+2;//开始匹配
for(i=next;i<=len-1;i++) 第 2 章 栈、队列、链表
{
if(a[i]!=s[top])
break;
top--;
}//如果top的值为0,则说明栈内所有的字符都被一一匹配了
if(top==0)
printf("YES");
else
printf("NO");
getchar();getchar();
return 0;
}

纸牌游戏:

  星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓
鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的
第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌
的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即
可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人
手中的牌全部出完时,游戏结束,对手获胜。
  假如游戏开始时,小哼手中有 6 张牌,顺序为 2 4 1 2 5 6,小哈手中也有 6 张牌,顺序
3 1 3 5 6 4,最终谁会获胜呢?现在你可以拿出纸牌来试一试。接下来请你写一个程序来
自动判断谁将获胜。这里我们做一个约定,小哼和小哈手中牌的牌面只有 1~9

 完整代码实现

#include <stdio.h> 
struct queue 
{ int data[1000]; int head; int tail; 
}; 
第 2 章 栈、队列、链表
struct stack 
{ int data[10]; int top; 
}; 
int main() 
{ struct queue q1,q2; struct stack s; int book[10]; int i,t; //初始化队列q1.head=1; q1.tail=1; q2.head=1; q2.tail=1; //初始化栈s.top=0; //初始化用来标记的数组,用来标记哪些牌已经在桌上for(i=1;i<=9;i++) book[i]=0; //依次向队列插入6个数//小哼手上的6张牌for(i=1;i<=6;i++) { scanf("%d",&q1.data[q1.tail]); q1.tail++; } //小哈手上的6张牌for(i=1;i<=6;i++) { scanf("%d",&q2.data[q2.tail]); q2.tail++; } while(q1.head<q1.tail && q2.head<q2.tail ) //当队列不为空的时候执行循环{ t=q1.data[q1.head];//小哼出一张牌//判断小哼当前打出的牌是否能赢牌if(book[t]==0) //表明桌上没有牌面为t的牌
41
混混藏书阁:http://book-life.blog.163.com
啊哈!算法
42 { //小哼此轮没有赢牌q1.head++; //小哼已经打出一张牌,所以要把打出的牌出队s.top++; s.data[s.top]=t; //再把打出的牌放到桌上,即入栈book[t]=1; //标记桌上现在已经有牌面为t的牌} else { //小哼此轮可以赢牌q1.head++;//小哼已经打出一张牌,所以要把打出的牌出队q1.data[q1.tail]=t;//紧接着把打出的牌放到手中牌的末尾q1.tail++; while(s.data[s.top]!=t) //把桌上可以赢得的牌依次放到手中牌的末尾{ book[s.data[s.top]]=0;//取消标记q1.data[q1.tail]=s.data[s.top];//依次放入队尾q1.tail++; s.top--; //栈中少了一张牌,所以栈顶要减1 } } t=q2.data[q2.head]; //小哈出一张牌//判断小哈当前打出的牌是否能赢牌if(book[t]==0) //表明桌上没有牌面为t的牌{ //小哈此轮没有赢牌q2.head++; //小哈已经打出一张牌,所以要把打出的牌出队s.top++; s.data[s.top]=t; //再把打出的牌放到桌上,即入栈book[t]=1; //标记桌上现在已经有牌面为t的牌 } else { //小哈此轮可以赢牌q2.head++;//小哈已经打出一张牌,所以要把打出的牌出队q2.data[q2.tail]=t;//紧接着把打出的牌放到手中牌的末尾q2.tail++; while(s.data[s.top]!=t) //把桌上可以赢得的牌依次放到手中牌的末尾{ book[s.data[s.top]]=0;//取消标记
第 2 章 栈、队列、链表q2.data[q2.tail]=s.data[s.top];//依次放入队尾q2.tail++; s.top--; } } } if(q2.head==q2.tail) { printf("小哼win\n"); printf("小哼当前手中的牌是"); for(i=q1.head;i<=q1.tail-1;i++) printf(" %d",q1.data[i]); if(s.top>0) //如果桌上有牌则依次输出桌上的牌{ printf("\n桌上的牌是"); for(i=1;i<=s.top;i++) printf(" %d",s.data[i]); } else printf("\n桌上已经没有牌了"); } else { printf("小哈win\n"); printf("小哈当前手中的牌是"); for(i=q2.head;i<=q2.tail-1;i++) printf(" %d",q2.data[i]); if(s.top>0) //如果桌上有牌则依次输出桌上的牌{ printf("\n桌上的牌是"); for(i=1;i<=s.top;i++) printf(" %d",s.data[i]); } else printf("\n桌上已经没有牌了"); } getchar();getchar(); return 0; 
}

链表

#include <stdio.h> 
#include <stdlib.h> 
int main() 
{ int *p; //定义一个指针p p=(int *)malloc(sizeof(int)); //指针p获取动态分配的内存空间地址*p=10; //向指针p所指向的内存空间中存入10 printf("%d",*p); //输出指针p所指向的内存中的值getchar();getchar(); return 0; 
}

书上关于链表的介绍: 

到这里你可能要问:为什么要用这么复杂的办法来存储数据呢?因为之前的方法,我们
必须预先准确地知道所需变量的个数,也就是说我们必须定义出所有的变量。比如我们定义
100 个整型变量,那么程序就只能存储 100 个整数,如果现在的实际情况是需要存储 101
个,那必须修改程序才可以。如果有一天你写的软件已经发布或者交付使用,却发现要存储
1000 个数才行,那就不得不再次修改程序,重新编译程序,发布一个新版本来代替原来的。
而有了 malloc 函数我们便可以在程序运行的过程中根据实际情况来申请空间。

例子: 

#include <stdio.h> 
#include <stdlib.h> 
//这里创建一个结构体用来表示链表的结点类型
struct node 
{ int data; struct node *next; 
}; 
int main() 
{ struct node *head,*p,*q,*t; int i,n,a; scanf("%d",&n); head = NULL;//头指针初始为空for(i=1;i<=n;i++)//循环读入n个数{ scanf("%d",&a); //动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点p=(struct node *)malloc(sizeof(struct node)); p->data=a;//将数据存储到当前结点的data域中p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空if(head==NULL) head=p;//如果这是第一个创建的结点,则将头指针指向这个结点else q->next=p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点q=p;//指针q也指向当前结点} //输出链表中的所有数t=head; while(t!=NULL) { 
第 2 章 栈、队列、链表printf("%d ",t->data); t=t->next;//继续下一个结点} getchar();getchar(); return 0; 
}容易造成内存泄漏!
上面这段代码没有释放动态申请的空间,虽然没有错误,但是这样会很不安全,有兴趣的朋友可以去了解一下 free 命令。
#include <stdio.h> 
#include <stdlib.h> 
//这里创建一个结构体用来表示链表的结点类型
struct node 
{ int data; struct node *next; 
}; 
int main() 
{ struct node *head,*p,*q,*t; int i,n,a; scanf("%d",&n); head = NULL;//头指针初始为空for(i=1;i<=n;i++)//循环读入n个数{ scanf("%d",&a); //动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点p=(struct node *)malloc(sizeof(struct node)); p->data=a;//将数据存储到当前结点的data域中p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空if(head==NULL) head=p;//如果这是第一个创建的结点,则将头指针指向这个结点else q->next=p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点
第 2 章 栈、队列、链表q=p;//指针q也指向当前结点} scanf("%d",&a);//读入待插入的数t=head;//从链表头部开始遍历while(t!=NULL)//当没有到达链表尾部的时候循环{ if(t->next->data > a)//如果当前结点下一个结点的值大于待插入数,将数插入到中间{ p=(struct node *)malloc(sizeof(struct node));//动态申请一个空间,
用来存放新增结点p->data=a; p->next=t->next;//新增结点的后继指针指向当前结点的后继指针所指向的结点t->next=p;//当前结点的后继指针指向新增结点break;//插入完毕退出循环} t=t->next;//继续下一个结点} //输出链表中的所有数t=head; while(t!=NULL) { printf("%d ",t->data); t=t->next;//继续下一个结点} getchar();getchar(); return 0; 
}

模拟链表 

链表可以用指针(上面的)和使用数组来实现的方式(叫做模拟链表)

#include <stdio.h> 
int main() 
{ int data[101],right[101]; int i,n,t,len; //读入已有的数 scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&data[i]); len=n; //初始化数组right for(i=1;i<=n;i++) { if(i!=n) right[i]=i+1; else right[i]=0; } //直接在数组data的末尾增加一个数 len++; scanf("%d",&data[len]); //从链表的头部开始遍历 t=1; while(t!=0) { if(data[right[t]]>data[len])//如果当前结点下一个结点的值大于待插入数,将
数插入到中间 { right[len]=right[t];//新插入数的下一个结点标号等于当前结点的下一个结
点编号 right[t]=len;//当前结点的下一个结点编号就是新插入数的编号 break;//插入完成跳出循环 } t=right[t]; } //输出链表中所有的数 t=1; while(t!=0) { printf("%d ",data[t]); t=right[t]; } getchar(); getchar(); return 0; 
}

使用模拟链表也可以实现双向链表和循环链表 

相关文章:

啊哈 算法读书笔记 第 2 章 栈、队列、链表

第 2 章 栈、队列、链表 目录 第 2 章 栈、队列、链表 队列&#xff1a; 解密回文——栈 纸牌游戏&#xff1a; 链表 模拟链表 队列&#xff1a; 首先将第 1 个数删除&#xff0c;紧接着将第 2 个数放到这串数的末尾&#xff0c;再将第 3 个数删除并将第 4 个数放到这串…...

Git ---- IDEA 集成 Git

Git ---- IDEA 集成 Git1. 配置 Git 忽略文件2. 定位 Git 程序3. 初始化本地库4. 添加到暂存区5. 提交到本地库6. 切换版本7. 创建分支8. 切换分支9. 合并分支10. 解决冲突1. 配置 Git 忽略文件 1. Eclipse 特定文件 2. IDEA 特定文件 3. Maven 工程的 target 目录 问题1…...

【LeetCode 704】【Go】二分查找

二分查找题解 一、碎碎念 从本周开始&#xff0c;重新更新刷题记录了哈。 基于费曼学习法的原理&#xff0c;最好的输入是输出&#xff0c;所以与大家分享。 鉴于目前这个糟糕的市场环境&#xff0c;还是要练好自己的基本技术&#xff0c;万一那天就被迫 N 1了&#xff0c;你…...

【代码随想录训练营】【Day23】第六章|二叉树|669. 修剪二叉搜索树 |108.将有序数组转换为二叉搜索树|538.把二叉搜索树转换为累加树

修剪二叉搜索树 题目详细&#xff1a;LeetCode.669 做这道题之前建议先看视频讲解&#xff0c;没有想象中那么复杂&#xff1a;代码随想录—修剪二叉搜索树 由题可知&#xff0c;需要删除节点值不在区间内的节点&#xff0c;所以可以得到三种情况&#xff1a; 情况一&#…...

CV——day78 读论文:通过静态背景构建扩展低通道路边雷达的探测距离(目标是规避风险)

Extending the Detection Range for Low-Channel Roadside LiDAR by Static Background Construction 通过静态背景构建扩展低通道路边雷达的探测距离I. INTRODUCTIONII. RELATED WORKA. LiDAR-Based 3-D Vehicle and Road User DetectionB. LiDAR Data Background FilteringC.…...

【编程入门】应用市场(go语言版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 《N种编程语言做个记事本》 目标 为编程初学者打造入门学习项目&#xff0c;使…...

Linux(openEuler)没有界面连接互联网方法

前言: 系统版本openEuleropenEuler-22.03-LTS-x86_64-dvd 我们在安装linux之后&#xff0c;一般都是无界面的情况。大部分情况都是需要自己安装界面的&#xff0c;如果路由器的情况下直接插上网络就好了。下面就开始介绍两种方法进行linxu网络的连接。 注意: 小编是使用的第一…...

第一天 软考中级--嵌入式系统设计师考试复习教程开始了

第一天 嵌入式系统设计师考试复习教程 第二天 软考中级--嵌入式系统设计师考试考试大纲解析 目录...

分享 10 个高频 Python 面试题

Python 很容易学会&#xff0c;但很难掌握。你可以在几天内了解它的基本语法&#xff0c;但是要能够用 Python 开发出足够好的商业软件&#xff0c;多年的实践是必须的。因为&#xff0c;无论你使用哪种编程语言&#xff0c;你都必须对其复杂的内部机制有足够的了解&#xff0c…...

ThreadLocal原理、结构、源码解析

文章目录一、Thread简介1.什么是ThreadLocal2.为什么要是用ThreadLocal2.1Synchronized、Lock保证线程安全2.2ThreadLocal保证线程安全3.ThreadLocal和Synchronized的区别二、ThreadLocal原理1.Thread抽象内部结构2.ThreadLocal源码2.1Thread、ThreadLocal、ThreadLocalMap、En…...

分布式之PBFT算法

写在前面 在分布式之拜占庭问题 一文中我们分析了拜占庭问题&#xff0c;并一起看了支持拜占庭容错的口信消息性和签名消息性算法&#xff0c;但是这两种算法都有一个非常严重的问题&#xff0c;就是消息数量太多&#xff0c;通信的成本太大&#xff0c;消息数量复杂度为O(n ^…...

Linux 操作系统——查看/修改系统时区、时间、本地时间修改为UTC

文章目录1.背景描述2.知识储备3.解决步骤1. 查看当前时区2.修改设置Linux服务器时区3.复制相应的时区文件&#xff0c;替换系统时区文件&#xff1b;或者创建链接文件4. 查看和修改Linux的时间5. 硬件时间和系统时间的 相互同步1.背景描述 最近一个项目日期采用java8的LocalDa…...

CSS数据类型以及符号

css数据类型定义的是css属性中具有代表性的值&#xff0c;在规范的语法格式中&#xff0c;使用关键字外加一对 <和>表示&#xff0c;例如数值类型<number>、色值类型<color>等。 举个例子&#xff1a;background-image这个css属性语法结构如下&#xff1a; …...

LeetCode-54. 螺旋矩阵

题目来源 54. 螺旋矩阵 题目思路 while循环只遍历"环"&#xff0c;不成环就不遍历了 四个边界 上边界 top : 0下边界 bottom : matrix.length - 1左边界 left : 0右边界 right : matrix[0].length - 1 矩阵不一定是方阵 top < bottom && left < r…...

【Python入门第十八天】Python For 循环

Python For 循环 for 循环用于迭代序列&#xff08;即列表&#xff0c;元组&#xff0c;字典&#xff0c;集合或字符串&#xff09;。 这与其他编程语言中的 for 关键字不太相似&#xff0c;而是更像其他面向对象编程语言中的迭代器方法。 通过使用 for 循环&#xff0c;我们…...

Qt图片定时滚动播放器

目录参考结构PicturePlay.promain.cpppictureplay.hpictureplay.cpppictureplay.ui效果源码参考 Qt图片浏览器 QT制作一个图片播放器 Qt中自适应的labelpixmap充满窗口后&#xff0c;无法缩小只能放大 可以显示jpg、jpeg、png、bmp。可以从电脑上拖动图到窗口并显示出来或者打开…...

李宏毅2023春季机器学习课程

目录2021&2022课程重磅须知我维护的其他项目更新日志课程地址课程资料直链课程作业直链其他优质课程2021&2022课程 CSDN Github 重磅须知 为方便所有网课资料与优质电子书籍的实时更新维护&#xff0c;创建一个在线实时网盘文件夹&#xff1b;   网盘获取方式&#…...

计算机操作系统知识点汇总

计算机操作系统选择填空题&#xff0c;300知识点&#xff0c;包含操作系统概论、处理机管理、内存管理、设备管理、文件管理等&#xff0c;为大学生期末创造奇迹提供无限可能 1、填空题 1、操作系统是对计算机资源进行管理的软件 2、操作系统是提供了处理机管理、 存储器管理…...

【离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表】

离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表离线数仓-8-数据仓库开发DWD层设计要点-交易域相关事实表一、DWD层设计要点二、交易域相关事实表1.交易域加购事务事实表1.加购事务事实表 前期梳理2.加购事务事实表 DDL表设计分析3.加购事务事实表 加载数据分析1.首日全…...

计算机网络(七):DNS协议和原理,DNS为什么用UDP,网页解析的全过程

文章目录一、什么是DNS二、DNS的作用三、DNS作用四、DNS为什么用UDP五、如果打开一个网站很慢&#xff0c;要如何排查六、网页解析的全过程一、什么是DNS DNS是域名系统的英文缩写&#xff0c;是一种组织成域层次结构的计算机和网络服务命名系统&#xff0c;用于TCP/IP网络。 …...

算法23:多叉树_派对的最大快乐值

公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、 没有环的多叉树。树的头节点是公司唯一的老板。除老板之外的每个员工都有唯一的直接上级。 叶节点是没有任何下属的基层员工(subordinates列表为空)&#xff0c;除基层员工外&#xff0c;每…...

中国ETC行业市场规模及未来发展趋势

中国ETC行业市场规模及未来发展趋势编辑根据市场调研在线网发布的2023-2029年中国ETC行业发展策略分析及战略咨询研究报告分析&#xff1a;随着政府坚持实施绿色出行政策&#xff0c;ETC行业也受到了极大的支持。根据中国智能交通协会统计&#xff0c;2017年中国ETC行业市场规模…...

每日刷题(一)——只出现一次的数字

前言 今天遇到一个位运算的题目&#xff0c;感觉很有意思&#xff0c;记录一下。 Question1 136. 只出现一次的数字 给你一个 非空 整数数组 nums &#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实…...

洛谷P5737 【深基7.例3】闰年展示 C语言/C++

【深基7.例3】闰年展示 题目描述 输入 x,yx,yx,y&#xff0c;输出 [x,y][x,y][x,y] 区间中闰年个数&#xff0c;并在下一行输出所有闰年年份数字&#xff0c;使用空格隔开。 输入格式 输入两个正整数 x,yx,yx,y&#xff0c;以空格隔开。 输出格式 第一行输出一个正整数&a…...

shell注释

注释对于任何编程语言都是不可忽视的重要组成部分&#xff0c;编写者通过注释来为其他人提供解释或提示&#xff0c;能有效提高代码的可读性。 Bash 同其他编程语言一样提供了两种类型注释的支持。 单行注释多行注释一、Bash 单行注释 在注释段落的开头使用 # &#xff0c;如下…...

【C++入门(上篇)】C++入门学习

前言&#xff1a; 在之前的学习中&#xff0c;我们已经对初阶数据结构进行相应了学习&#xff0c;加上之前C语言的学习功底。今天&#xff0c;我们将会踏上更高一级“台阶”的学习-----即C的学习&#xff01;&#xff01;&#xff01; 文章目录1.C 简介1.1什么是C1.2.C的发展史…...

【密码学】 一篇文章讲透数字签名

【密码学】 一篇文章讲透数字签名 数字签名介绍 数字签名&#xff08;又称公钥数字签名&#xff09;是只有信息的发送者才能产生的别人无法伪造的一段数字串&#xff0c;这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名…...

POI导入导出、EasyExcel批量导入和分页导出

文件导入导出POI、EasyExcel POI&#xff1a;消耗内存非常大&#xff0c;在线上发生过堆内存溢出OOM&#xff1b;在导出大数据量的记录的时候也会造成堆溢出甚至宕机&#xff0c;如果导入导出数据量小的话还是考虑的&#xff0c;下面简单介绍POI怎么使用 POI导入 首先拿到文…...

手把手教你做微信公众号

手把手教你做微信公众号 微信公众号可以通过注册的方式来建立。 1.进入微信公众平台 首先&#xff0c;在浏览器中搜索微信公众号&#xff0c;网页第一个就是&#xff0c;如下图所示&#xff0c;我们点进去。 2.注册微信平台账号 进入官网之后&#xff0c;如下图所示&#…...

python-在macOS上安装python库 xlwings失败的解决方式

问题&#xff1a;python库 xlwings安装失败 今天&#xff0c;看到网上有wlwings库&#xff0c;可以用来处理excel表格&#xff0c;立刻想试一试。结果&#xff0c;安装这个python库失败了。经过排查&#xff0c;问题解决。 安装过程和错误提示&#xff1a; 我用最简单直接的…...