mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-02-10 06:05:51 +08:00
更新串
This commit is contained in:
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"xstring": "cpp"
|
||||
}
|
||||
}
|
||||
237
Code/CPP-Code/head/link_string.h
Normal file
237
Code/CPP-Code/head/link_string.h
Normal file
@@ -0,0 +1,237 @@
|
||||
#include "head.h"
|
||||
|
||||
// 块链串结点
|
||||
class LinkStringNode {
|
||||
private:
|
||||
// 数据
|
||||
char *_data{};
|
||||
// 指针
|
||||
LinkStringNode *_next{};
|
||||
public:
|
||||
// 初始化数据
|
||||
bool SetData();
|
||||
|
||||
bool SetData(int data_size);
|
||||
|
||||
// 设置数据
|
||||
bool SetData(char *character);
|
||||
|
||||
bool SetData(int index, char character);
|
||||
|
||||
// 获取数据
|
||||
char *GetData();
|
||||
|
||||
char GetData(int index);
|
||||
|
||||
// 设置指针
|
||||
bool SetNext();
|
||||
|
||||
bool SetNext(LinkStringNode *next);
|
||||
|
||||
// 获取指针
|
||||
LinkStringNode *GetNext();
|
||||
|
||||
// 初始化
|
||||
LinkStringNode();
|
||||
|
||||
explicit LinkStringNode(int max_size);
|
||||
|
||||
LinkStringNode(int max_size, LinkStringNode *next);
|
||||
|
||||
LinkStringNode(int max_size, char *character, LinkStringNode *next);
|
||||
|
||||
LinkStringNode(int max_size, char *character);
|
||||
};
|
||||
|
||||
bool LinkStringNode::SetData() {
|
||||
this->_data = new char[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkStringNode::SetData(int data_size) {
|
||||
this->_data = new char[data_size];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkStringNode::SetData(char *character) {
|
||||
this->_data = character;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkStringNode::SetData(int index, char character) {
|
||||
this->_data[index] = character;
|
||||
return true;
|
||||
}
|
||||
|
||||
char *LinkStringNode::GetData() {
|
||||
return this->_data;
|
||||
}
|
||||
|
||||
char LinkStringNode::GetData(int index) {
|
||||
return this->_data[index];
|
||||
}
|
||||
|
||||
bool LinkStringNode::SetNext() {
|
||||
this->_next = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkStringNode::SetNext(LinkStringNode *next) {
|
||||
this->_next = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkStringNode *LinkStringNode::GetNext() {
|
||||
return this->_next;
|
||||
}
|
||||
|
||||
LinkStringNode::LinkStringNode() {
|
||||
this->SetData();
|
||||
this->SetNext();
|
||||
}
|
||||
|
||||
LinkStringNode::LinkStringNode(int max_size) {
|
||||
this->SetData(max_size);
|
||||
this->SetNext();
|
||||
}
|
||||
|
||||
LinkStringNode::LinkStringNode(int max_size, LinkStringNode *next) {
|
||||
this->SetData(max_size);
|
||||
this->SetNext(next);
|
||||
}
|
||||
|
||||
LinkStringNode::LinkStringNode(int max_size, char *character, LinkStringNode *next) {
|
||||
this->SetData(max_size);
|
||||
for (int i = 0; i < max_size; i++) {
|
||||
if (character[i] != '\0') {
|
||||
this->SetData(i, character[i]);
|
||||
}
|
||||
}
|
||||
this->SetNext(next);
|
||||
}
|
||||
|
||||
LinkStringNode::LinkStringNode(int max_size, char *character) {
|
||||
this->SetData(max_size);
|
||||
for (int i = 0; i < max_size; i++) {
|
||||
if (character[i] != '\0') {
|
||||
this->SetData(i, character[i]);
|
||||
}
|
||||
}
|
||||
this->SetNext();
|
||||
}
|
||||
|
||||
class LinkString {
|
||||
private:
|
||||
// 头尾指针
|
||||
LinkStringNode *_front{}, *_rear{};
|
||||
// 块链长度
|
||||
int _data_size{};
|
||||
// 长度
|
||||
int _length{};
|
||||
public:
|
||||
// 设置头指针
|
||||
bool SetFront();
|
||||
bool SetFront(LinkStringNode *front);
|
||||
|
||||
// 获取头指针
|
||||
LinkStringNode *GetFront();
|
||||
|
||||
// 设置尾指针
|
||||
bool SetRear();
|
||||
bool SetRear(LinkStringNode *rear);
|
||||
|
||||
// 获取尾指针
|
||||
LinkStringNode *GetRear();
|
||||
|
||||
// 设置总体块链单元长度
|
||||
bool SetDataSize();
|
||||
|
||||
bool SetDataSize(int data_size);
|
||||
|
||||
// 获取数据长度
|
||||
int GetDataSize() const;
|
||||
|
||||
// 数据长度自加
|
||||
bool SetLength();
|
||||
|
||||
// 设置数据长度
|
||||
bool SetLength(int length);
|
||||
|
||||
// 获取数据长度
|
||||
int GetLength() const;
|
||||
|
||||
// 初始化
|
||||
LinkString();
|
||||
|
||||
explicit LinkString(int data_size);
|
||||
};
|
||||
|
||||
bool LinkString::SetFront() {
|
||||
this->_front = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkString::SetFront(LinkStringNode *front) {
|
||||
this->_front = front;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkStringNode *LinkString::GetFront() {
|
||||
return this->_front;
|
||||
}
|
||||
|
||||
bool LinkString::SetRear() {
|
||||
this->_rear = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkString::SetRear(LinkStringNode *rear) {
|
||||
this->_rear = rear;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkStringNode *LinkString::GetRear() {
|
||||
return this->_rear;
|
||||
}
|
||||
|
||||
bool LinkString::SetDataSize() {
|
||||
this->_data_size = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkString::SetDataSize(int data_size) {
|
||||
this->_data_size = data_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
int LinkString::GetDataSize() const {
|
||||
return this->_data_size;
|
||||
}
|
||||
|
||||
bool LinkString::SetLength() {
|
||||
this->_length++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkString::SetLength(int length) {
|
||||
this->_length = length;
|
||||
return true;
|
||||
}
|
||||
|
||||
int LinkString::GetLength() const {
|
||||
return this->_length;
|
||||
}
|
||||
|
||||
LinkString::LinkString() {
|
||||
this->SetFront();
|
||||
this->SetRear();
|
||||
this->SetLength(0);
|
||||
this->SetDataSize(1);
|
||||
}
|
||||
|
||||
LinkString::LinkString(int data_size) {
|
||||
this->SetFront();
|
||||
this->SetRear();
|
||||
this->SetLength(0);
|
||||
this->SetDataSize(data_size);
|
||||
}
|
||||
118
Code/CPP-Code/head/sequence_string.h
Normal file
118
Code/CPP-Code/head/sequence_string.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "head.h"
|
||||
|
||||
// 顺序串
|
||||
class SequenceString{
|
||||
private:
|
||||
// 数据
|
||||
char* _data{};
|
||||
// 长度
|
||||
int _length{};
|
||||
// 最大容量
|
||||
int _max_size{};
|
||||
public:
|
||||
// 设置数据
|
||||
bool SetData();
|
||||
|
||||
bool SetData(int max_size);
|
||||
|
||||
bool SetData(char *character);
|
||||
|
||||
bool SetData(int index, char character);
|
||||
|
||||
// 获取数据
|
||||
char* GetData();
|
||||
|
||||
char GetData(int index);
|
||||
|
||||
// 长度自加
|
||||
bool SetLength();
|
||||
|
||||
// 设置长度
|
||||
bool SetLength(int length);
|
||||
|
||||
// 获取长度
|
||||
int GetLength() const;
|
||||
|
||||
// 设置最大容量
|
||||
bool SetMaxSize();
|
||||
|
||||
bool SetMaxSize(int max_size);
|
||||
|
||||
// 获取最大容量
|
||||
int GetMaxSize() const;
|
||||
|
||||
// 构造函数
|
||||
SequenceString();
|
||||
|
||||
explicit SequenceString(int max_size);
|
||||
};
|
||||
|
||||
bool SequenceString::SetData() {
|
||||
this->_data = new char[MAXSIZE];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SequenceString::SetData(int max_size) {
|
||||
this->_data = new char[max_size];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SequenceString::SetData(char * character) {
|
||||
this->_data = character;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SequenceString::SetData(int index, char character) {
|
||||
this->_data[index] = character;
|
||||
return true;
|
||||
}
|
||||
|
||||
char *SequenceString::GetData() {
|
||||
return this->_data;
|
||||
}
|
||||
|
||||
char SequenceString::GetData(int index) {
|
||||
return this->_data[index];
|
||||
}
|
||||
|
||||
bool SequenceString::SetLength() {
|
||||
this->_length++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SequenceString::SetLength(int length) {
|
||||
this->_length = length;
|
||||
return true;
|
||||
}
|
||||
|
||||
int SequenceString::GetLength() const {
|
||||
return this->_length;
|
||||
}
|
||||
|
||||
bool SequenceString::SetMaxSize() {
|
||||
this->_max_size = MAXSIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SequenceString::SetMaxSize(int max_size) {
|
||||
this->_max_size = max_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
int SequenceString::GetMaxSize() const {
|
||||
return this->_max_size;
|
||||
}
|
||||
|
||||
SequenceString::SequenceString() {
|
||||
this->SetData();
|
||||
this->SetMaxSize();
|
||||
this->SetLength(0);
|
||||
}
|
||||
|
||||
SequenceString::SequenceString(int max_size) {
|
||||
this->SetData(max_size);
|
||||
this->SetMaxSize();
|
||||
this->SetLength(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "../head/link_stack.h"
|
||||
#include "../head/sequence_queue.h"
|
||||
#include "../head/link_queue.h"
|
||||
#include "../head/sequence_string.h"
|
||||
#include "../head/link_string.h"
|
||||
|
||||
bool SequenceListTest() {
|
||||
DynamicSequenceList list;
|
||||
|
||||
@@ -2,5 +2,9 @@
|
||||
#define MAXSIZE 5
|
||||
// 定义默认值
|
||||
#define DEFAULTELEM '\0'
|
||||
// 定义默认串值
|
||||
#define DEFAULTCHAR '\0'
|
||||
// 定义串块链数据长度
|
||||
#define DATASIZE 4
|
||||
// 定义默认数据类型
|
||||
typedef char element_type;
|
||||
@@ -7,6 +7,12 @@ typedef struct LinkListNode {
|
||||
} LinkListNode, *LinkList;
|
||||
|
||||
// 初始化
|
||||
bool InitLinkList(LinkList &list) {
|
||||
list->data = DEFAULTELEM;
|
||||
list->next = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkList InitLinkList() {
|
||||
auto list = (LinkList) malloc(sizeof(LinkList));
|
||||
list->data = DEFAULTELEM;
|
||||
@@ -14,12 +20,6 @@ LinkList InitLinkList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
bool InitLinkList(LinkList &list) {
|
||||
list->data = DEFAULTELEM;
|
||||
list->next = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 判空
|
||||
bool EmptyLinkList(LinkList list) {
|
||||
return list->next == nullptr && list->data == DEFAULTELEM;
|
||||
|
||||
@@ -4,8 +4,8 @@ typedef struct LinkStackNode{
|
||||
// 数据
|
||||
element_type data;
|
||||
// 指针
|
||||
struct LinkStackNode *next;
|
||||
} *LinkStack;
|
||||
LinkStackNode *next;
|
||||
} LinkStackNode, *LinkStack;
|
||||
|
||||
// 初始化
|
||||
LinkStack InitLinkStack(){
|
||||
|
||||
25
Code/Code/head/link_string.h
Normal file
25
Code/Code/head/link_string.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "head.h"
|
||||
|
||||
// 块链串结点
|
||||
typedef struct LinkStringNode {
|
||||
// 数据
|
||||
char *data;
|
||||
// 指针
|
||||
LinkStringNode *next;
|
||||
} LinkStringNode, *LinkString;
|
||||
|
||||
bool InitLinkString(LinkString &string) {
|
||||
string->data = (char *) malloc(sizeof(char) * DATASIZE);
|
||||
string->next = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkString InitLinkString() {
|
||||
auto* string = (LinkString) malloc(sizeof(LinkString));
|
||||
string->data = (char *) malloc(sizeof(char) * DATASIZE);
|
||||
string->next = nullptr;
|
||||
return (LinkString &)string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
41
Code/Code/head/sequence_string.h
Normal file
41
Code/Code/head/sequence_string.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "head.h"
|
||||
|
||||
// 顺序串
|
||||
typedef struct {
|
||||
// 数据
|
||||
char *data;
|
||||
// 长度
|
||||
unsigned int length;
|
||||
// 最大容量
|
||||
unsigned int max_size;
|
||||
} SequenceString;
|
||||
|
||||
bool InitSequenceString(SequenceString &string) {
|
||||
string.data = (char *) malloc(sizeof(char) * MAXSIZE);
|
||||
string.max_size = MAXSIZE;
|
||||
string.length = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InitSequenceString(SequenceString &string, int max_size) {
|
||||
string.data = (char *) malloc(sizeof(char) * max_size);
|
||||
string.max_size = max_size;
|
||||
string.length = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
SequenceString InitSequenceString() {
|
||||
auto *string = (SequenceString *) malloc(sizeof(SequenceString));
|
||||
string->data = (char *) malloc(sizeof(char) * MAXSIZE);
|
||||
string->max_size = MAXSIZE;
|
||||
string->length = 0;
|
||||
return (SequenceString &) string;
|
||||
}
|
||||
|
||||
SequenceString InitSequenceString(int max_size) {
|
||||
auto *string = (SequenceString *) malloc(sizeof(SequenceString));
|
||||
string->data = (char *) malloc(sizeof(char) * max_size);
|
||||
string->max_size = max_size;
|
||||
string->length = 0;
|
||||
return (SequenceString &) string;
|
||||
}
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "../head/share_stack.h"
|
||||
#include "../head/sequence_queue.h"
|
||||
#include "../head/link_queue.h"
|
||||
#include "../head/sequence_string.h"
|
||||
#include "../head/link_string.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
@@ -10,22 +10,25 @@
|
||||
|
||||
串的基本操作是对子串的操作。
|
||||
|
||||
## 顺序串
|
||||
## 串定义
|
||||
|
||||
### 顺序串
|
||||
|
||||
顺序串的结构定义方案
|
||||
|
||||
+ 使用单独的变量length保存串长。
|
||||
+ 使用data[0]记录串长;使得字符位序与数组下标一致;但是由于char类型一个为一字节大小,所以能表示的数字是0到255,太大的串无法表示。
|
||||
+ 没有表示串长的变量,使用\0表示串结尾,对应ASCII码的0号字符。
|
||||
+ data[0]空余,使用单独的变量length保存串长,这个比较常用。
|
||||
+ 使用单独的变量$length$保存串长。
|
||||
+ 使用$data[0]$记录串长;使得字符位序与数组下标一致;但是由于$char$类型一个为一字节大小,所以能表示的数字是$0$到$255$,太大的串无法表示,大于的部分会被截断。
|
||||
+ 没有表示串长的变量,使用$\backslash0$表示串结尾,对应$ASCII$码的$0$号字符。
|
||||
+ $data[0]$空余,使用单独的变量$length$保存串长,这个比较常用。
|
||||
+ 可以定长分配也可以用堆分配。
|
||||
|
||||
## 链串
|
||||
### 链串
|
||||
|
||||
如一般的链式存储结构定义一样,定义一个数据与指向下一位的指针。
|
||||
|
||||
但是如果你只在每个结点定义了一个字节的数据,但是又包含了四个字节的指针,那么存储利用率会很低。
|
||||
|
||||
如果是顺序表数据类型是整数类型,那么这种利用率低的情况确实无可奈何,但是对于串而言,因为一个字节存储一个字符,所以能一个字节存一个字符类型数据,所以为了提升数据存储利用率,可以每个结点存等多个字符。
|
||||
如果是顺序表数据类型是整数类型,那么这种利用率低的情况确实无可奈何,但是对于串而言,因为一个字节存储一个字符,所以能一个字节存一个字符类型数据,所以为了提升数据存储利用率,可以每个结点存等多个字符。这个就是块链串。
|
||||
|
||||
## 模式匹配
|
||||
|
||||
@@ -33,15 +36,15 @@
|
||||
|
||||
### 朴素模式匹配算法
|
||||
|
||||
从主串T、模式串P(子串)的第一个位置开始比较(i=0,j=0),若相等,则 i,j各自+1,然后比较下一个字符。若不等,主串指针回溯到上一轮比较位置的下一个位置,子串回溯到0,再进行下一次比较。令子串长度为m,主串长度为n:
|
||||
从主串$T$、模式串$P$(子串)的第一个位置开始比较($i=0,j=0$),若相等,则$i$,$j$各自$+1$,然后比较下一个字符。若不等,主串指针回溯到上一轮比较位置的下一个位置,子串回溯到$0$,再进行下一次比较。令子串长度为$m$,主串长度为$n$:
|
||||
|
||||
+ 匹配成功的最好时间复杂度:$O(m)$:刚好第一个就匹配上了,总对比次数为子串长度。
|
||||
+ 匹配失败的最好时间复杂度:$O(n-m+1)=O(n-m)=O(n)$:匹配成功之前,每一个与第一个字符都匹配失败。
|
||||
+ 匹配失败的最坏时间复杂度:$O(nm-m^2+m)= O(nm)$:子串除了最后一个对不上,其余的都能对上,则每次遍历完一边后,又要走回头路;直到匹配成功/失败一共需要比较$m\times(n-m+1)$次。m:每次需要移动m次,i需要移动$n-m+1$次。
|
||||
+ 匹配失败的最坏时间复杂度:$O(nm-m^2+m)= O(nm)$:子串除了最后一个对不上,其余的都能对上,则每次遍历完一边后,又要走回头路;直到匹配成功/失败一共需要比较$m\times(n-m+1)$次。$m$:每次需要移动$m$次,$i$需要移动$n-m+1$次。
|
||||
|
||||
### KMP算法
|
||||
|
||||
KMP算法是对朴素模式匹配算法的优化。
|
||||
$KMP$算法是对朴素模式匹配算法的优化。
|
||||
|
||||
朴素模式匹配算法的缺点就是当某些子串与模式串能部分匹配时,主串的扫描指针i经常回溯,从而导致时间开销。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ $C.88$
|
||||
|
||||
$D.89$
|
||||
|
||||
解:$B$。根据公式$k=2i+j-3$。但是这种公式很难记忆,所以直接找规律。
|
||||
解:$B$。根据公式$k=2i+j-3$。但是这种公式很难记忆,所以直接找规律。观察三对角矩阵不难发现,第一行有两个元素,剩下的在元素$m_{30,30}$所在行之前的$28$行中,每行都有$3$个元素,而$m_{30,30}$之前仅有一个元素$m_{30,29}$,不难发现元素$m_{30,30}$在数组$N$中的下标是$2+28\times3+2-1=87$。
|
||||
|
||||
**例题** 若将$n$阶上三角矩阵$A$按列优先级压缩存放在一维数组$B[1\cdots n(n+1)/2+1]$中,则存放到$B[k]$中的非零元素$a_{i,j}($1\leqslant i,j\leqslant n$)的下标$i$、$j$与$k$的对应关系是()。
|
||||
|
||||
@@ -24,6 +24,8 @@ $C.j(j-1)/2+i$
|
||||
|
||||
$D.j(j-1)/2+i-1$
|
||||
|
||||
解:$C$。按列优先存储,故元素$a$,前面有$j-1$列,共有$1+2+3+\cdots+j-1=j(j-1)/2$个元素,元素$a_{i,j}$在第$j$列上是第$i$个元素,数组$B$的下标是从$1$开始,因此$k=j(j-1)/2+i$。
|
||||
|
||||
**例题** 若将$n$阶下三角矩阵$A$按列优先顺序压缩存放在一维数组$B[1\cdots n(n+1)/2+1]$中,则存放到$B[k]$中的非零元素$a_{i,j}$($1\leqslant i,j\leqslant n$)的下标$i,j$与$k$的对应关系是()。
|
||||
|
||||
$A.(j-1)(2n-j+1)/2+i-j$
|
||||
@@ -34,6 +36,8 @@ $C.(j-1)(2n-j+2)/2+i-j$
|
||||
|
||||
$D.(j-1)(2n-j+1)/2+i-j-1$
|
||||
|
||||
解:$B$。按列优先存储,故元素$a_{i,j}$之前有$j-1$列,共有$n+(n-1)+\cdots+(n-j+2)=(j-1)(2n-j+2)/2$个元素,元素$a_{i,j}$是第$j$列上第$i-j+1$个元素,数组$B$下标从$1$开始,$k=(j-1)(2n-j+2)/2+i-j+1$。
|
||||
|
||||
**例题** 设有一个$12\times12$的对称矩阵$M$,将其上三角部分的元素$m_{i,j}$($1\leqslant i\leqslant j\leqslant12$)按行优先存入$C$语言的一维数组$N$中,元素$m_{7,2}$在$N$中的下标是()。
|
||||
|
||||
$A.50$
|
||||
@@ -43,3 +47,5 @@ $B.51$
|
||||
$C.55$
|
||||
|
||||
$D.66$
|
||||
|
||||
解:$A$。在$C$语言中,数组$N$的下标从$0$开始。第一个元素$m_{1,1}$对应存入$n_0$,矩阵$M$的第一行有$12$个元素,第二行有$11$个,第三行有$10$个,第四行有$9$个,第五行有$8$个,所以$m_{6,6}$。是第$12+11+10+9+8+1=51$个元素,下标应为$50$。
|
||||
|
||||
Reference in New Issue
Block a user