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

数据结构--》探索数据结构中的字符串结构与算法

        本文将带你深入了解串的基本概念、表示方法以及串操作的常见算法。通过深入理解串的相关概念和操作,我们将能够更好地应用它们来解决算法问题。

        无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握串在数据结构和算法中的重要性,进而提升算法解题的能力。接下来让我们开启数据结构与算法的奇妙之旅吧。

目录

串的定义与基本操作

串的存储结构

串的模式匹配算法

串的常见应用


串的定义与基本操作

串(也称字符串)是由零个或多个字符组成的有限序列。在计算机科学中,串通常被定义为一个字符数组,其长度可以是任意的。一般记为  S = 'a_1a_2····a_n'  (n \geq 0)

其中,S是串名,单引号括起来的字符序列是串的值;a_i 可以是字母、数字或其他字符;串中字符的个数n称为串的长度。n = 0 时的串称为空串(用 \Phi 表示)

例如:S = "HelloWorld!"   T = 'iPhone 15 Pro Max'   注意:字符串有的语言用双引号,有的单引号

子串:串中任意个连续的字符组成的子序列。   Eg:‘iPhone’、'Pro M' 是串T的子串

主串:包含子串的串。                                       Eg:T是子串 'iPhone' 的主串

字符在主串中的位置”:字符在串中的序号。     Eg:'1' 在T中的位置是8(第一次出现)位序从1

子串在主串的位置:第一字符在主串的位置。   Eg:'11 Pro' 在T中的位置为8

空串: M = '' ;空格串:N = '    '

串是一种特殊的线性表,数据元素之间呈线性关系:

串的数据对象限定为字符集(如中文字符、英文字符、数字字符、标点字符等),串的基本操作如增删改查等通常以子串为操作对象。串的基本操作如下(以C语言举例,这里仅仅是介绍概念):

StrAssign(&T,chars):赋值操作。把串T赋值为chars。

StrCopy(&T,S):复制操作。由串复制得到串T。

StrEmpty(S):判空操作。若S为空串,则返回TRUE,否则返回FALSE。

StrLength(S):求串长。返回串S的元素个数。

ClearString(&S):清空操作。将S清为空串。

DestroyString(&S):销毁串。将串S销毁(回收存储空间)。

Concat(&T,S1,S2):串联接。用T返回由S1和S2联接而成的新串。

SubString(&Sub,S,pos,len):求子串。用Sub返回串S的第pos个字符起长度为len的子串。

Index(S,T):定位操作。若主串S中存在与串T值相同的子串,则返回它在主串S中第一次出现的位置;否则函数值为0。

StrCompare(S,T):比较操作。若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0。

假设有串 T='' ,S='iPhone 15 Pro Max?',W='Pro'

Eg:执行如下基本操作返回相应的结果如下:

Concat(&T,S,W)后,T='iPhone 15 Pro Max?Pro'

SubString(&T,S,4,6)后,T='one 15'

Index(S,W)后,返回值为11

回顾重点,其主要内容整理成如下内容: 

串的存储结构

串是一种特殊的线性表,我们以什么样的方式实现线性表同样我们也可以用什么样的方式实现串

顺序存储:将一个串中的各个字符按照顺序依次存放在一段连续的存储空间中,称为串的顺序存储,具有随机访问的特点。

串的顺序存储结构通常使用字符数组来实现,每个字符都占据一个数组元素,因此在定义字符数组时需要保证空间足够容纳整个字符串。在C语言中,可以使用以下方式定义一个长度为n的字符数组str,用于存储最长长度为n-1的字符串:

char str[n];

当然字符串的顺序存储结构也可以使用动态数组来实现,这种方法需要在运行时根据字符串的长度动态分配内存空间。

下面是C语言中实现字符串顺序存储的一些基本操作:

#include <stdio.h>
#include <stdlib.h>  //需要include<stdlib.h>库函数#define MAX_SIZE 1000 //定义字符串最大长度typedef struct {char str[MAX_SIZE];int length;
} SeqString;//初始化串
void InitSeqString(SeqString* S, char* str) {int i = 0;while (str[i]) {  //统计字符串长度++i;}S->length = i;for (i = 0; i < S->length; ++i) {S->str[i] = str[i];}
}//获取串长
int LengthSeqString(SeqString S) {return S.length;
}//获取某个位置的字符
char GetSeqString(SeqString S, int i) {if (i < 1 || i > S.length) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}return S.str[i - 1];
}//修改某个位置上的字符
void SetSeqString(SeqString* S, int i, char ch) {if (i < 1 || i > S->length) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}S->str[i - 1] = ch;
}//在某个位置插入字符
void InsertSeqString(SeqString* S, int i, char ch) {if (i < 1 || i > S->length + 1) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}if (S->length >= MAX_SIZE) {  //判断是否越界printf("The string is full.\n");exit(1);}for (int j = S->length - 1; j >= i - 1; --j) {  //从后往前依次向后移动字符S->str[j + 1] = S->str[j];}S->str[i - 1] = ch;++S->length;  //串长加1
}//删除某个位置上的字符
void DeleteSeqString(SeqString* S, int i) {if (i < 1 || i > S->length) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}for (int j = i; j < S->length; ++j) {  //从前往后依次向前移动字符S->str[j - 1] = S->str[j];}--S->length;  //串长减1
}//清空串
void ClearSeqString(SeqString* S) {S->length = 0;
}//复制串
void CopySeqString(SeqString S, SeqString* T) {T->length = S.length;for (int i = 0; i < S.length; ++i) {T->str[i] = S.str[i];}T->str[T->length] = '\0';  //在复制后的字符串尾部加上结束符'\0'
}//连接两个串
void ConcatSeqString(SeqString* S, SeqString T) {if (S->length + T.length <= MAX_SIZE) {  //判断是否超出最大长度for (int i = 0; i < T.length; ++i) {S->str[i + S->length] = T.str[i]; //将T中的字符复制到S末尾}S->length += T.length;} else {printf("The new string exceeds the maximum length.\n");}
}//比较两个串是否相等
int CompareSeqString(SeqString S, SeqString T) {if (S.length != T.length) {  //如果长度不相等,直接返回0return 0;}for (int i = 0; i < S.length; ++i) {if (S.str[i] != T.str[i]) { //如果某个字符不相等,返回0return 0;}}return 1;
}int main() {SeqString S, T;char str1[] = "Hello World!";char str2[] = "This is a test.";InitSeqString(&S, str1);printf("Length of S: %d\n", LengthSeqString(S));  //13printf("Character at position 6 of S: %c\n", GetSeqString(S, 6));  //WSetSeqString(&S, 7, 'X');printf("Modified string: %s\n", S.str); //Hello WXrld!InitSeqString(&T, str2);InsertSeqString(&T, 3, 'x');printf("Inserted string: %s\n", T.str);  //Thix is a test.DeleteSeqString(&S, 6);printf("Deleted string: %s\n", S.str); //Hello Xrld!CopySeqString(T, &S);printf("Copied string: %s\n", S.str); //Thix is a test.ConcatSeqString(&S, T);printf("Concatenated string: %s\n", S.str); //Thix is a test.Thix is a test.ClearSeqString(&S);printf("Length of S: %d\n", LengthSeqString(S));  //0printf("S and T are%s equal.\n", CompareSeqString(S, T) ? "" : " not"); //S and T are not equal.return 0;
}

链式存储: 使用链表的方式存储一个字符串。与顺序存储不同,链式存储可以实现动态分配内存,无需预先确定字符串长度,可以灵活地进行插入、删除等操作。

串的链式存储可以采用单向链表、双向链表或循环链表来实现,每个节点存储一个字符。为方便起见,通常在链表末尾添加一个空字符表示该串结束。对于空串,可以定义一个只包含头结点的链表。

下面是C语言中实现字符串链式存储的一些基本操作:

#include <stdio.h>
#include <stdlib.h>  //需要include<stdlib.h>库函数typedef struct LNode {char data;struct LNode *next;
} LNode, *LinkList;//初始化一个空串
void InitString(LinkList* L) {*L = (LinkList)malloc(sizeof(LNode));  //创建头结点(*L)->next = NULL;
}//判断是否为空串
int IsEmpty(LinkList L) {return L->next == NULL;
}//获取串长
int LengthString(LinkList L) {int len = 0;LNode *p = L->next;while (p) {++len;p = p->next;}return len;
}//获取某个位置的字符
char GetChar(LinkList L, int i) {if (i < 1 || i > LengthString(L)) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}LNode *p = L->next;int k = 1;while (k < i) {p = p->next;++k;}return p->data;
}//在某个位置插入字符
void InsertChar(LinkList* L, int i, char ch) {if (i < 1 || i > LengthString(*L) + 1) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}LNode *p = *L, *q;int k = 1;while (k < i) {p = p->next;++k;}q = (LNode*)malloc(sizeof(LNode));  //创建新结点q->data = ch;q->next = p->next;p->next = q;
}//删除某个位置上的字符
void DeleteChar(LinkList* L, int i) {if (i < 1 || i > LengthString(*L)) {  //判断位置是否合法printf("Position %d is invalid.\n", i);exit(1);}LNode *p = *L, *q;int k = 1;while (k < i) {p = p->next;++k;}q = p->next;p->next = q->next;free(q);  //释放被删除的结点
}//清空串
void ClearString(LinkList* L) {LNode *p = (*L)->next, *q;while (p) {q = p->next;free(p);  //释放结点内存p = q;}(*L)->next = NULL;
}//复制串
void CopyString(LinkList S, LinkList* T) {LNode *p = S->next, *q, *r;*T = (LinkList)malloc(sizeof(LNode));  //创建头结点r = *T;while (p) {q = (LNode*)malloc(sizeof(LNode));  //创建新结点q->data = p->data;r->next = q;r = q;p = p->next;}r->next = NULL;
}//连接两个串
void ConcatString(LinkList* S, LinkList T) {LNode *p = (*S)->next;while (p->next) {  //找到S的尾结点p = p->next;}p->next = T->next;  //将T中的结点添加到S末尾free(T);  //释放T的头结点
}//比较两个串是否相等
int CompareString(LinkList S, LinkList T) {LNode *p = S->next, *q = T->next;while (p && q && p->data == q->data) {  //依次比较两个串中每个字符p = p->next;q = q->next;}if (!p && !q) {  //如果两个串长度相等且所有字符相等,返回1return 1;} else {return 0;}
}int main() {LinkList S, T;InitString(&S);printf("Is S empty? %s\n", IsEmpty(S) ? "Yes" : "No");  //YesInsertChar(&S, 1, 'H');InsertChar(&S, 2, 'e');InsertChar(&S, 3, 'l');InsertChar(&S, 4, 'l');InsertChar(&S, 5, 'o');printf("Length of S: %d\n", LengthString(S));  //5printf("Character at position 3 of S: %c\n", GetChar(S, 3));  //lDeleteChar(&S, 2);printf("Modified string: ");for (LNode *p = S->next; p; p = p->next) {printf("%c", p->data);}printf("\n"); //HelloInitString(&T);InsertChar(&T, 1, 'W');InsertChar(&T, 2, 'o');InsertChar(&T, 3, 'r');InsertChar(&T, 4, 'l');InsertChar(&T, 5, 'd');printf("Are S and T equal? %s\n", CompareString(S, T) ? "Yes" : "No"); //NoClearString(&S);printf("Is S empty? %s\n", IsEmpty(S) ? "Yes" : "No"); //YesCopyString(T, &S);printf("Copied string: ");for (LNode *p = S->next; p; p = p->next) {printf("%c", p->data);}printf("\n"); //WorldConcatString(&S, T);printf("Concatenated string: ");for (LNode *p = S->next; p; p = p->next) {printf("%c", p->data);}printf("\n"); //WorldWorldreturn 0;
}

回顾重点,其主要内容整理成如下内容: 

串的模式匹配算法

串的模式匹配算法用于在一个主串中查找某个子串的出现位置或匹配情况。常见的模式匹配算法包括朴素算法(暴力算法)和 KMP算法

朴素算法

原理:从主串的第一个字符开始,逐个比较主串和子串对应位置的字符,若不匹配,则将子串向后移动一位,再进行比较,直到子串完全匹配或主串遍历完毕。

实现方式:使用两个指针分别指向主串和子串,进行逐个比较。

代码示例:

int naiveStringMatch(const string& text, const string& pattern) {int n = text.length();int m = pattern.length();for (int i = 0; i <= n - m; i++) {int j;for (j = 0; j < m; j++) {if (text[i + j] != pattern[j]) {break;}}if (j == m) {return i;  // 匹配成功,返回子串在主串中的起始位置}}return -1;  // 未找到匹配的子串
}

回顾重点,其主要内容整理成如下内容: 

KMP算法

原理:通过预处理模式串构建部分匹配表,根据部分匹配表中的信息进行跳跃匹配,避免重复比较已经匹配过的字符。

实现方式:使用两个指针分别指向主串和子串,并维护一个部分匹配表。

相关图例如下:

代码示例:

void buildPartialMatchTable(const string& pattern, vector<int>& table) {int m = pattern.length();table.resize(m);table[0] = 0;int len = 0;int i = 1;while (i < m) {if (pattern[i] == pattern[len]) {len++;table[i] = len;i++;} else {if (len > 0) {len = table[len - 1];} else {table[i] = 0;i++;}}}
}int kmpStringMatch(const string& text, const string& pattern) {int n = text.length();int m = pattern.length();vector<int> table;buildPartialMatchTable(pattern, table);int i = 0;  // 主串的指针int j = 0;  // 子串的指针while (i < n) {if (text[i] == pattern[j]) {i++;j++;if (j == m) {return i - j;  // 匹配成功,返回子串在主串中的起始位置}} else {if (j > 0) {j = table[j - 1];  // 根据部分匹配表进行跳跃} else {i++;}}}return -1;  // 未找到匹配的子串
}

next数组:在KMP算法中,next数组(也称为部分匹配表)是用于辅助模式串匹配的数据结构。它存储了在模式串中,每个位置的最长相同前缀后缀的长度。在考研的过程中我们也需要根据提供的模式串T来求解出next数组:

接下来我们已google模式串进行举例如何计算出相应的next数组的值:

next[1]第一个字符不匹配时:

next[2]第二个字符不匹配时: 

next[3]第三个字符不匹配时:

next[4]第四个字符不匹配时:

next[5]第五个字符不匹配时:

next[6]第六个字符不匹配时:

使用next数组:在上文我们已经通过手算的方式得出next数组,接下来我们开始对该next数组进行相应的使用,起具体的主串如下,模式串就用我们之前得到next数组的字符串google:

在上面我们给出了具体的主串,这里我们将主串和模式串进行依次的匹配,直到第六个没有匹配成功, 也就是说当j为6的时候匹配失败,所以我们需要令 j = next[j] = 1 (j=6)。所以接下来我们需要令模式串在下面的这个位置开始匹配:

在上面的位置我们还是发现主串和模式串不匹配,而且是在第一个字符情况下,所以这里我们我们的 j = next[1] = 0,如果我们检测到j为0的话就需要i和j都进行++操作,也就是开始匹配下一个字符串:

在上面的主串和模式串对比中我们发现在第五个字符串的时候出现了不同如下:

·所以在保持i不变的情况下,我们需要令 j = next[5] = 2 ,也就是从j为2的时候开始匹配:

到此为止我们发现主串和模式串的所以字符都能匹配, 所以google的模式串就匹配成功了:

优化next数组后的nextval数组:在上文讲解的next数组是有地方可以进行优化的,这里不再讲解其原因,就直接告诉你如何在得知next数组相应值的情况下求出nextval数组:

nextval首位无脑写0

next[2]=1这里我们看到next数组序号2模式串b与序号1 a不等,即nextval[2]=next[2]=1

next[3]=1这里我们看到next数组序号3模式串a与序号1 a相等,即nextval[3]=next[1]=0

next[4]=2这里我们看到next数组序号4模式串b与序号2 b相等,即nextval[4]=next[2]=1

next[5]=3这里我们看到next数组序号5模式串a与序号3 a相等,即nextval[5]=next[3]=0

next[6]=4这里我们看到next数组序号6模式串a与序号4 b不等,即nextval[6]=next[6]=4

串的常见应用

串(String)是由零个或多个字符组成的有限序列,在数据结构中有着广泛的应用。下面是串在数据结构中常见的应用:

  1. 文本处理:串广泛应用于文本编辑、搜索和替换等操作。例如,可以使用串来表示、存储和处理文本文件、文章、代码等。

  2. 数据压缩:在数据压缩算法中,串有着重要的作用。常见的压缩算法如LZW、Huffman编码等利用了串的统计特性,对文本数据进行压缩和解压缩操作。

  3. 数据库系统:在数据库系统中,经常需要处理字符串类型的数据,如存储用户的姓名、地址、电话号码等信息。串的操作如匹配、比较、拼接等在数据库查询和数据处理中非常常见。

  4. 编译器和解释器:在编译器和解释器中,串被广泛用于表示源代码、词法分析、语法分析等。编译器通过对源代码进行分析和处理,将其转化为可执行的机器语言。

  5. 字符串匹配和搜索算法:串的匹配和搜索算法是串应用的核心领域之一。KMP算法、Boyer-Moore算法、正则表达式等算法都是基于串的匹配和搜索操作。

  6. 加密算法:在数据加密和安全领域,串常用于表示和处理密钥、密码、哈希值等信息。加密算法如AES、DES等对字符串进行加密和解密操作。

  7. 网络协议:在网络通信中,串被广泛应用于各种协议的数据传输中,如HTTP、SMTP等。通过串的拼接、分割等操作,实现了数据的可靠传输和通信。

这些只是串在数据结构中的一些常见应用领域,实际上串在计算机科学中的应用非常广泛,几乎涵盖了各个领域。

相关文章:

数据结构--》探索数据结构中的字符串结构与算法

本文将带你深入了解串的基本概念、表示方法以及串操作的常见算法。通过深入理解串的相关概念和操作&#xff0c;我们将能够更好地应用它们来解决算法问题。 无论你是初学者还是进阶者&#xff0c;本文将为你提供简单易懂、实用可行的知识点&#xff0c;帮助你更好地掌握串在数据…...

云安全之等级保护详解

等级保护概念 网络安全等级保护&#xff0c;是对信息系统分等级实行安全保护&#xff0c;对信息系统中使用的安全产品实行按等级管理&#xff0c;对信息系统中发生的信息安全事件分等级进行响应、处置。 网络安全等级保护的核心内容是&#xff1a;国家制定统一的政策、标准&a…...

VUE状态持久化,储存动态路由

1. vuex persistPlugin.js 文件 const routerKey "ROUTER_KEY";export default (store) > {// 刷新页面时&#xff0c;存储改变的数据window.addEventListener("beforeunload", () > {localStorage.setItem(routerKey, JSON.stringify(store.stat…...

微信小程序代驾系统源码(含未编译前端,二开无忧) v2.5

简介&#xff1a; 如今有越来越多的人在网上做代驾&#xff0c;打造一个代驾平台&#xff0c;既可以让司机增加一笔额外的收入&#xff0c;也解决了车主酒后不能开发的问题&#xff0c;代驾系统基于微信小程序开发的代驾系统支持一键下单叫代驾&#xff0c;支持代驾人员保证金…...

1797_GNU pdf阅读器evince

全部学习汇总&#xff1a; GreyZhang/g_GNU: After some years I found that I do need some free air, so dive into GNU again! (github.com) 近段时间经历了很多事情&#xff0c;终于想找一点技术上的自由气氛。或许&#xff0c;没有什么比GNU的一些软件探索更适合填充这样的…...

网络-跨域解决

文章目录 前言一、跨域是什么&#xff1f;二、跨域的解决1.JSONP2.前端代理dev环境3.后端设置请求头CORS4.运维nginx代理 总结 前言 本文主要介绍跨域问题介绍并提供了四种解决办法。 一、跨域是什么&#xff1f; 准确的来说是浏览器存在跨域问题&#xff0c;浏览器为了安全考…...

git提交代码的流程

1.拉取代码 当你进入了一家公司就需要拉去公司的代码进行开发,此时你的项目小组长会给你个地址拉代码, git clone 公司项目的地址 此时如果不使用了这个方式拉去代码,拉去的是master分支上的代码,但是很多数的情况下&#xff0c;公司的项目可能会在其它的分支上,因此到公…...

【SpringBoot】配置文件详解

配置文件详解 一. 配置文件作用二. 配置文件的格式1. properties 配置文件说明①. properties 基本语法②. 读取配置⽂件③. properties 缺点 2. yml 配置⽂件说明①. yml 基本语法②. yml 使用进阶 3. properties VS yml 三. 设置不同环境的配置⽂件 一. 配置文件作用 整个项…...

一文讲懂-五险一金

假设在“北京”&#xff1a;这里的数值并不代表任何真实的城市或地区&#xff0c;只是为了说明计算方法。 工资: 月工资为 6000 元。养老保险: 单位比例: 20% 个人比例: 8%医疗保险: 单位比例: 10% 个人比例: 2%失业保险: 单位比例: 2% 个人比例: 0.5%工伤保险: 单位比例: 0.5…...

判断三条边是否构成三角形(Python实现)

组成三角形的三条边a,b,c需满足条件: ab>c ac>b bc>a 已知&#xff1a;三角形任意三条边的长度之和大于第三条边。 解题&#xff1a;定义3个变量a、b、c&#xff0c;让用户输入任意三个数字赋值给三个变量。判断三个变量中是否任意两个之和大于第三个数值。 判断条件之…...

The directory ‘*‘ or its parent directory is not owned by the current user

python安装编译时出现如下错误 The directory /home/admin/.cache/pip/http or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may …...

leetcode做题笔记162. 寻找峰值

峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums&#xff0c;找到峰值元素并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O(…...

nginx负载转发源请求http/https:X-Forwarded-Proto及nginx中的转发报头

今天在排查服务器的问题时最后定位到服务器因为经过了运维这一层的处理&#xff0c;转发过来的请求不管用户请求的是https还是http&#xff0c;我们的proxy服务器收到的都是80端口上的http。于是联系相关部门了解有没有现成的可用的这样一个字段来获得这个值。公司用的也是标准…...

Docker compose插件安装

添加docker源 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/do…...

【数据结构与算法】树、二叉树的概念及结构(详解)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--树以及二叉树的概念与结构 目录 一.树概念及结构 1.树的概念 1.1树与非树 树的特点&#xff1…...

函数指针数组指针(指向函数指针数组的指针)

一、什么是函数指针数组指针&#xff1f; 本质是指针&#xff0c;指向函数指针数组&#xff0c;存放函数指针数组的地址。 代码如下&#xff1a; pfArr是函数指针数组 p是函数指针数组指针 int main() {int(*pfArr[])(int, int) { Add,Sub };//函数指针数组int(*(*p)[])(int, …...

经典算法-----汉诺塔问题

前言 今天我们学习一个老经典的问题-----汉诺塔问题&#xff0c;可能在学习编程之前我们就听说过这个问题&#xff0c;那这里我们如何去通过编程的方式去解决这么一个问题呢&#xff1f;下面接着看。 汉诺塔问题 问题描述 这里是引用汉诺塔问题源自印度一个古老的传说&#x…...

博客之站项目测试报告

项目背景项目功能测试计划Bug总结升级自动化测试正常登录流程 项目背景 1&#xff1a;博客之站系统是采用前后端分离的方式来实现&#xff1b;使用MySQL、Redis数据库储存相关数据&#xff1b;同时部署到云服务器上。 2&#xff1a;包含注册页、登录页、博客列表页、个人列表页…...

k8s晋级之管理容器的计算资源

概述 在 Kubernetes 中创建工作负载时&#xff0c;您可以为 Pod 中的每一个容器指定其所需要的内存&#xff08;RAM&#xff09;大小和 CPU 数量。如果这些信息被指定了&#xff0c;Kubernetes 调度器可以更好的决定将 Pod 调度到哪一个节点。对于容器来说&#xff0c;其所需要…...

计算机竞赛 深度学习火车票识别系统

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 图像识别 火车票识别系统 该项目较为新颖&#xff0c;适…...

盒子阴影和网页布局

盒子阴影 box-shadow: 10px 10px 10px 4px rgba(0,0,0,.3);//最后一个是透明度 传统网页布局的三种方式 标准流 就是按照规定好的默认方式排列 1.块级元素&#xff1a;div、hr、p、h1~h2、ul、ol、dl、form、table 行内元素会按照书顺序&#xff0c;从左到右顺序排列&#…...

Ph.D,一个Permanent head Damage的群体

一个群体 Permanent head Damage 的博士生群体 Permanent head Damage Ph.D 博士生一年级的同学们&#xff0c;不要担忧或高兴得太早&#xff0c;抱歉你们还没有经历Qualification——预备考试&#xff0c;你们暂且不能被称为博士&#xff0c;只能称自己是要努力成为博士预备…...

visual studio禁用qt-vsaddin插件更新

visual studio里qt-vsaddin插件默认是自动更新的&#xff0c;由于qt-vsaddin插件新版本的操作方式与老版本相差较大&#xff0c;且新版本不稳定&#xff0c;容易出Bug&#xff0c;所以需要禁用其自动更新&#xff0c;步骤如下&#xff1a;     点击VS2019菜单栏上的【扩展】–…...

Docker通过Dockerfile创建Redis、Nginx--详细过程

创建Nginx镜像 我们先创建一个目录&#xff0c;在目录里创建Dockerfile [rootdocker-3 ~]# mkdir mynginx [rootdocker-3 ~]# cd mynginx [rootdocker-3 ~]# vim Dockerfile Dockerfile的内容 FROM daocloud.io/library/centos:7 RUN buildDepsreadline-devel pcre-devel o…...

关于使用 uniapp Vue3 开发分享页面 语法糖 setup 开发获取ref踩坑

上代码 前端代码 <!-- 分享弹出 --> <uni-popup ref"share" type"share" safeArea backgroundColor"#fff"><uni-popup-share></uni-popup-share> </uni-popup>处理函数 import {onNavigationBarButtonTap} from…...

Springboot+vue的时间管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的时间管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的时间管理系统&#xff0c;采用M&#xff08;model&#xff0…...

企业如何实时监管员工聊天转账行为

你还在担心员工飞单、私单吗&#xff1f; 你还在担心员工辱骂删除客户吗&#xff1f; 你还在担心员工离职会带走公司客户吗&#xff1f; 你还在担心员工工作不认真&#xff0c;工作量无法统计吗&#xff1f; 。。。。。。。。 在当今互联网时代&#xff0c;企业微信的应用已…...

2.2.3.1vim + ctags + cscope + taglist

在window下,我们一般用Source Insight来查看代码而在linux下,使用vim来查看代码,vim是一个简单的文本浏览/编辑器,它可以通过插件的形式,搭建一个完全的类Source Insight环境,通过快捷键的形式,快速查看、定位变量/函数,本文就是基于vim,通过ctags+cscope+taglist+Ner…...

JAVA面经整理(4)

一)Volitaile关键字的作用: 1)保证多线程环境下共享变量的可见性&#xff0c;对于一个线程对于一个共享表变量的修改&#xff0c;其他线程可以立即看到修改之后的共享变量的值 2)可以增加内存屏障来放置多个指令之间的重排序 volatile的使用:常常用于一写多读的情况下&#xff…...

Python3数据科学包系列(一):数据分析实战

Python3中类的高级语法及实战 Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案 Python3数据科学包系列(一):数据分析实战 Python3数据科学包系列(二):数据分析实战 认识下数据科学中数据处理基础包: (1)NumPy 俗话说: 要学会跑需先…...

彩票网站怎么做代理/手机如何制作网页

代码简介&#xff1a; 用JavaScript判断远程图片是否存在&#xff0c;不存在话则替换指定的图片&#xff0c;指定图片可以是你网站的LOGO或其它图片&#xff0c;或显示提示信息。没想到用JS还能干这种活&#xff0c;以前都是用笨方法&#xff0c;也就是用ASP/PHP程序去判断&…...

做网站的支付/seo翻译

1、使用浏览器 1.1、获取当前IP(限制 1200次 /小时) 用浏览器访问 http://ip.hahado.cn/current-ip 输入用户名和密码 [{"ip": "180.102.181.64","ttl": 262.87515091896057} ] "ip"&#xff1a; 字段是当前的外网IP ("ip&qu…...

个人网站制作程序/绍兴seo推广公司

[下载程序文件]&#xff1a;点击下载此文件:DinoSAP程序&#xff1a;DinoSap结构力学求解器(版本v1.0)点击下载此文件:DinoSAP程序相关的例题【Bilibili视频网站】学习几个例题的建模与结构力学求解。https://www.bilibili.com/video/BV1LK41137UH[小记]这个是原来DinoBox的结构…...

网站建设类的手机软件/郑州seo排名工具

netstat -tlnnetstat -tulnp转载于:https://blog.51cto.com/robertleepeak/197492...

python h5网站开发/企业营销策划有限公司

以下代码是在学习过程中&#xff0c;网上查到的。如果有版权问题&#xff0c;请联系删帖&#xff01;&#xff01;&#xff01; 在网上找到了两种方法 一种是直接使用 .Net的类&#xff0c;测试后发现比如输入数字 8&#xff0c; 会自动变成 0.0.0.8 而这种格式并非我们所要的。…...

html5网站是用什么软件做的/地推一手项目平台

shared_ptr&#xff1a;资源管理利器 如果你还在使用传统的C&#xff0c;那么可以肯定堆内存的管理让你头痛过&#xff01;在传统的C领域&#xff0c;堆内存管理上我们能借用的现成工具就只有auto_ptr。但是很不幸用auto_ptr管理堆内存简直就是个错误。auto_ptr的问题可以归结为…...