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

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

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

目录

串的定义与基本操作

串的存储结构

串的模式匹配算法

串的常见应用


串的定义与基本操作

串(也称字符串)是由零个或多个字符组成的有限序列。在计算机科学中,串通常被定义为一个字符数组,其长度可以是任意的。一般记为  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等。通过串的拼接、分割等操作,实现了数据的可靠传输和通信。

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在PHP8中使用instanceof操作符检测对象类型-PHP8知识详解

在PHP8中使用instanceof操作符可以检测当前对象属于哪个类。语法格式如下&#xff1a; objectName instanceof classname下面我们用一个实例来讲解使用instanceof操作符检测对象类型。 本实例将将创建3个类&#xff0c;其中有两个类是父类和子类的关系&#xff0c;然后实例化…

JAVA学习(5)-全网最详细~

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

leetCode 376.摆动序列 贪心算法

如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如&#xff0c; [1, 7, 4, 9, 2, 5] 是一个 摆动序列 &…

图像拼接后丢失数据,转tiff报错rasterfile failed: an unknown

图像拼接后丢失数据 不仅是数据丢失了&#xff0c;还有个未知原因报错 部分数据存在值不存在的情况 原因 处理遥感数据很容易&#xff0c;磁盘爆满了 解决方案 清理一些无用数据&#xff0c;准备买个2T的外接硬盘用着了。 然后重新做处理

[Linux] 4.常用初级指令

pwd&#xff1a;显示当前文件路径 ls:列出当前文件夹下有哪些文件 mkdir空格文件名&#xff1a;创建一个新的文件夹 cd空格文件夹名&#xff1a;进入文件夹 cd..&#xff1a;退到上一层文件夹 ls -a&#xff1a;把所有文件夹列出来 .代表当前文件夹 ..代表上层文件夹 用…

【Vue】Vuex详解,一文读懂并使用Vuex

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

【15】c++设计模式——>抽象工厂模式

在海贼世界中&#xff0c;位于水之都的弗兰奇一家是由铁人弗兰奇所领导的以拆船为职业的家族&#xff0c;当然了他们的逆向工程做的也很好&#xff0c;会拆船必然会造船。船是海贼们出海所必备的海上交通工具&#xff0c;它由很多的零件组成&#xff0c;从宏观上看它有这么几个…

智慧财务管家,记录分析收支明细,轻松掌握财务情况并随时打印保存!

在日常的财务管理中&#xff0c;准确记录和分析收支明细是掌握财务情况、制定科学预算和实现财务目标的重要一环。然而&#xff0c;繁琐的手动记录和分析过程常常让我们感到头痛。现在&#xff0c;让我们向您推荐一款智慧财务管家&#xff0c;帮助您轻松记录和分析收支明细&…

仿函数的学习

仿函数 也叫 函数对象 仿函数是什么东西&#xff1f; 当你第一眼看到下面的代码的时候&#xff0c;你会觉得它是一个函数的调用&#xff1a; bool result less(a, b);但是我如果告诉你&#xff0c;less 是一个我自定义的一个类的对象呢&#xff1f; class Less { public:bo…

Interference Signal Recognition Based on Multi-Modal Deep Learning

系统结构 基于决策的融合实际上是用损失函数监督融合模型 其中 N N N是训练样本的数量 体会 作者未解释公式4的 t i t_i ti​的含义且不公布代码

elment以及elementPlus选中组件出现黑框问题解决!!

目录 问题&#xff1a; 图示&#xff1a; 解决方案&#xff1a; 问题&#xff1a; 使用elementPlus的按钮组件&#xff0c;点击按钮后会出现黑框&#xff0c;除非点击其他地方才能取消掉&#xff08;之前使用elment-ui其它组件时也出现过&#xff09; 图示&#xff1a; 解决方案…

Day-07 修改 Nginx 配置文件

至此&#xff1a; 简单的 Docker 安装 Nginx并启动算是成功了! ps: 如何修改 Nginx的配置、更改nginx 的资源文件&#xff1f; eg&#xff1a; 1、可以将容器中的目录和本机目录做映射。 2、达到修改本机目录文件就影响到容器中的文件。 1.本机创建实例文件夹 新建目录&#x…

【机器学习-黑马程序员】人工智能、机器学习概述

文章目录 前言一、人工智能概述二、什么是机器学习二、机器学习算法分类三、机器学习开发流程 前言 本专栏文章为观看黑马程序员《python机器学习》所做笔记&#xff0c;课程地址在这。如有侵权&#xff0c;立即删除。 一、人工智能概述 机器学习和人工智能、深度学习的关系 机…

即时通讯软件

通信协议 发送消息可以是个struct 客户端分两个线程&#xff1a;读取服务器&#xff0c;给服务器发&#xff08;否则会导致阻塞&#xff09; read和write的第二个参数类型是&#xff1a;void *buf——————不仅仅是一个字符串&#xff0c;也可以是一个结构体等等&#xf…

获取沪深300的所有个股列表

脚本&#xff1a; import requests from bs4 import BeautifulSoupurl "https://q.stock.sohu.com/cn/bk_4444.shtml" response requests.get(url) soup BeautifulSoup(response.text, "html.parser")# 找到包含class为e1的元素 elements soup.find_a…

NodeMCU ESP8266硬件开发板的熟悉

文章目录 硬件开发环境的熟悉基础介绍什么是 ESP8266 NodeMCU&#xff1f;NodeMCU芯片ESP12-E 模组开发板 ESP8266 版本引脚图Power GND I2CGPIOADCUARTSPIPWMControl 总结 硬件开发环境的熟悉 基础介绍 什么是 ESP8266 NodeMCU&#xff1f; ESP8266是乐鑫开发的一款低成本 …

阿里云服务器搭建网站(图文新手教程)

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流程&#xff1a; …

TempleteMethod

TempleteMethod 动机 在软件构建过程中&#xff0c;对于某一项任务&#xff0c;它常常有稳定的整体操作结构&#xff0c;但各个子步骤却有很多改变的需求&#xff0c;或者由于固有的原因 &#xff08;比如框架与应用之间的关系&#xff09;而无法和任务的整体结构同时实现。如…

【进程管理】初识进程

一.何为进程 教材一般会给出这样的答案: 运行起来的程序 或者 内存中的程序 这样说太抽象了&#xff0c;那我问程序和进程有什么区别呢&#xff1f;诶&#xff1f;这我知道&#xff0c;书上说&#xff0c;动态的叫进程&#xff0c;静态的叫程序。那么静态和动态又是什么意思…

坦克世界WOT知识图谱三部曲之爬虫篇

文章目录 关于坦克世界1. 爬虫任务2. 获取坦克列表3. 获取坦克具体信息结束语 关于坦克世界 《坦克世界》(World of Tanks, WOT)是我在本科期间玩过的一款战争网游&#xff0c;由Wargaming公司研发。2010年10月30日在俄罗斯首发&#xff0c;2011年4月12日在北美和欧洲推出&…