系列文章目录
第一章 线性表
第二章 栈与队列
第三章 串
第四章 数组与广义表
文章目录
前言
串,即字符串(String),是由零个或多个字符组成的有限序列。一般记为s="a_{1},a_{2},…,a_{n} "
其中,s是串名,引号(单/双引号都可)括起来的字符序列是串的值;a_{i}可以是字母、数字或其他字符;字符下标从1开始,串中字符的个数n称为串的长度。n=0时的串称为空串(用∅表示)。
子串:串中任意个连续的字符组成的子序列。主串:包含子串的串。
字符在主串中的位置:字符在串中的序号。(注意位序从1开始,而不是0)
子串在主串中的位置:子串的第一个字符在主串中的位置。
一、串
1.什么是串
串:限定数据元素类型的线性表。
空串:长度为0。
子串:串中任意个连续字符组成的子序列。
两串相等:两串长度相等,对应的每个字符相等。
子串(subString):串中任意几个连续的字符组成的子序列即为该串的子串
主串:相应地,包含该子串的串称为主串
子串的位置(index):子串在主串中首次出现时,该子串的首字符对应在主串中的序号,即为子串在主串中的位置。
这里有一个很经典的例子用来辅助说明。例如,设A和B分别为 A=‘This is a string’ B=‘is’ 则B是A的子串,A为主串。B在A中出现了两次,其中首次出现所对应的主串位置是3。因此,称B在A中的位置为3。 特别地,空串是任意串的子串,任意串是其自身的子串。
连接 (concatenation):连接是一个重要的二进制操作。对于任意两个主串中的子串s和t,它们的连接根据放置s和t 的前后顺序来定符号序列。例如,子串s = love,t = hug,那么st 就是lovehug,ts 就是huglove。
前缀和后缀 prefixes and suffixes:字符串s 可以说是t 的前缀,如果存在一个字符串u 满足条件t =su。如果u 是非空的,那么可以说s 是t 的一个合适的前缀;相应地,串s 可以说t 的后缀如果存在一个串u 满足条件t=us。如果u 是非空的,s 可以说是t 的一个合适的后缀。前缀和后缀可以说是t 的子串。
旋转:串s = uv 可以被说成t 的旋转如果t = vu. 举个例子,当u = 00110, v = 01的时候,串0011001 是0100110 的旋转。
逆转:串的逆转就是具有相同符号单顺序相反的字符串。例如,如果s=abc(a、b和c是字母表中符号),那么s 的逆转就是cba。一个与自身相反的字符串(例如,s=madam,逆转还是madam)被称为回文 palindrome,它还包括空字符串和所有长度为1的字符串。
2.串的基本操作
函数 | 功能 |
---|---|
strcpy(p, p1) | 复制字符串 |
strncpy(p, p1, n) | 复制指定长度字符串 |
strcat(p, p1) | 附加字符串 |
strncat(p, p1, n) | 附加指定长度字符串 |
strlen(`p) | 取字符串长度 |
strcmp(p, p1) | 比较字符串 |
strcasecmp(p, p1) | 忽略大小写比较字符串 |
strncmp(p, p1, n) | 比较指定长度字符串 |
strchr(p, c) | 在字符串中查找指定字符 |
strrchr(p, c) | 在字符串中反向查找 |
strstr(p, p1) | 查找字符串 |
3.串的存储
静态(定长)顺序结构
Typedef char String[MAXSIZE+1];
动态(堆分配)顺序结构
typedef struct
{
char *ch;
int length;
}String;
4.判断字符串是否为空StrEmpty
int StrEmpty(char a[]) {
if (a[0] == '\0') {
return -1;
}
return 0;
}
5.求字符串长度Str_len
int Str_len(char a[]) {
int len;
for ( len = 0; a[len] !='\0';)
{
len++
}
return len;
}
6.字符串拼接Str_cat
void str_cat(char a[], char b[]) {
int i,j;
i = strlen(b);
for (j = 0; a[j] != '\0'; j++)
{
b[j + i] = a[j];
}
}
7.字符串截取substring
void substring(char a[], int pos, int len, char* c) {
int i,j=0;
for ( i = pos; i <pos+len; i++)
{
c[j] = a[i];
j++;
}
c[len] = '\0';
}
8.字符串拷贝str_copy
void str_copy(char a[], char b[]) {
int len = strlen(b);
for (int i = 0; i < len; ++i) {
a[i] = b[i];
}
}
9.字符串替换str_replace
//替换 Replace(&S,T,V) 用V替换主串S中出现的所有与T相等的不重叠的子串
10.字符串插入insert_str
void insert_str(char b[], int pos, char* c) {
int i,len_b = strlen(b),j=0,len_c = strlen(c);
int insert_pos = pos;
if (pos > len_b) {
return;
}
for (j = 0; j < len_c; j++) {
for (i = len_b; i >= pos; i--) {
b[i + 1] = b[i];
}
pos++;
len_b++;
}
//puts(b);
for (i = insert_pos, j = 0; i < insert_pos + len_c; i++) {
b[i] = c[j];
j++;
}
}
10.字符串删除delete_str
//StrDelete(&S,pos,len) 从串S中删除第pos个字符起长度为len的子串
11.字符串释放DestroyString
//释放 DestroyString(&S)
二、字串串匹配算法
1.kmp
代码如下(示例):
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int kmp(char a[], char b[], int next[]);
int get_next(char b[], int next[]);
int main() {
char a[20] = "aaaadascaafgh";
char b[10] = "adascaa";
int next[] = { -1,0,0,1,0,0,1 };
int c = kmp(a, b, next);
if (c >= 0) {
printf("匹配成功,在第%d个位置匹配成功\n", c + 1);
}
else {
printf("匹配失败\n");
}
int next1[7];
get_next(b, next1);
for(int i = 0; i <= 6; i++) {
printf("%d \n", next[i]);
}
}
int get_next(char b[], int next[]) {
int i = 0, j = -1;
int m = strlen(b);
next[0] = -1;
while (i <= m - 2) {
if (j == -1 || b[i] == b[j]) {
next[i + 1] = j + 1;
++i;
++j;
}
else {
j = next[j];
}
}
}
int kmp(char a[], char b[], int next[]) {
int i=0, j=0;
int m = strlen(a),n=strlen(b);
while (i <= m-1 && j <= n-1)
{
if ( j == -1 || a[i] == b[j]) {
i++;
j++;
}
else {
j = next[j];
}
}
if (j >= n ) {
return i - n;
}
else {
return -1;
}
}
2.求next[]数组
代码如下(示例):(期末考试不要求掌握,但得会手写next数组)
int get_next(char b[], int next[]) {
int i = 0, j = -1;
int m = strlen(b);
next[0] = -1;
while (i <= m - 2) {
if (j == -1 || b[i] == b[j]) {
next[i + 1] = j + 1;
++i;
++j;
}
else {
j = next[j];
}
}
}
2.BF
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void main() {
char s[] = "abceeffqq88w";
char t[] = "fqq8";
int pos, index;
printf("请输入您要查找子串的起始位置\n");
scanf("%d", &pos);
index = BF(s, t, pos);
printf("%s在%s中的起始位置为:%d\n", t, s, index);
}
int BF(char s[], char t[], int pos) {
int i, j;
if (pos<0 || pos>strlen(s)) {
printf("pos error !\n");
return;
}
i = pos; j=0;
while (t[j]!='\0' && s[i] != '\0') {
if (s[i] == t[j]) {
i++; j++;
}else {
i = i - j + 1;
j = 0;
}
}
if (t[j] == '\0') {
return i - strlen(t);
}else {
return -1;
}
}
总结
只是写了部分基础的东西为了考试做得笔记