一、字符串的存储结构与基本运算
- 字符串结构体定义(动态分配内存方式)
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 字符串结构体
typedef struct String {
char *content;
int length;
} String;
- 字符串初始化函数
c
// 初始化字符串
String* string_init(const char *str) {
String *s = (String *)malloc(sizeof(String));
if (str == NULL) {
s->content = NULL;
s->length = 0;
return s;
}
s->length = strlen(str);
s->content = (char *)malloc((s->length + 1) * sizeof(char));
strcpy(s->content, str);
return s;
}
笔记:
- 首先为
String
结构体分配内存。如果输入字符串指针str
为NULL
,则字符串内容指针设为NULL
,长度为 0。 - 若
str
不为NULL
,计算其长度,然后为字符串内容分配足够的内存(长度加 1,用于存储字符串结束符'\0'
),最后使用strcpy
将输入字符串复制到新分配的内存中。
- 求字符串长度函数
c
// 获取字符串长度
int string_length(String *s) {
return s->length;
}
笔记:直接返回字符串结构体中的长度成员。
- 字符串连接函数
c
// 连接两个字符串
String* string_concat(String *s1, String *s2) {
String *result = (String *)malloc(sizeof(String));
result->length = s1->length + s2->length;
result->content = (char *)malloc((result->length + 1) * sizeof(char));
strcpy(result->content, s1->content);
strcat(result->content, s2->content);
return result;
}
笔记:
- 先创建一个新的
String
结构体用于存储连接后的结果。计算新字符串的长度为两个输入字符串长度之和。 - 为新字符串内容分配内存,先将
s1
的内容复制到新字符串中,再使用strcat
将s2
的内容连接到后面。
- 字符串比较函数
c
// 比较两个字符串
int string_compare(String *s1, String *s2) {
return strcmp(s1->content, s2->content);
}
笔记 :利用标准库函数strcmp
来比较两个字符串,根据返回值判断大小关系(返回值小于 0:s1
小于s2
;等于 0:s1
等于s2
;大于 0:s1
大于s2
)。
二、字符串模式匹配算法(BF 算法)
c
// BF(Brute - Force)模式匹配算法
int BF_Match(String *text, String *pattern) {
int i = 0, j = 0;
int textLen = text->length;
int patternLen = pattern->length;
while (i < textLen && j < patternLen) {
if (text->content[i] == pattern->content[j]) {
i++;
j++;
} else {
i = i - j + 1;
j = 0;
}
}
if (j == patternLen) {
return i - patternLen;
}
return -1;
}
笔记:
- 该算法从文本字符串
text
和模式字符串pattern
的起始位置开始逐个字符比较。 - 当
text
和pattern
当前位置字符相等时,同时移动两个字符串的指针。 - 若遇到不匹配的字符,
text
的指针回溯到本次匹配开始位置的下一个字符,pattern
的指针重新回到起始位置。 - 当
pattern
的所有字符都匹配成功(j == patternLen
)时,返回模式字符串在文本字符串中的起始位置(i - patternLen
),若遍历完文本字符串仍未完全匹配,则返回 -1。
以下是一个简单的测试函数:
c
int main() {
String *s1 = string_init("abcdef");
String *s2 = string_init("cde");
String *s3 = string_concat(s1, s2);
printf("Length of s1: %d\n", string_length(s1));
printf("Result of comparison between s1 and s2: %d\n", string_compare(s1, s2));
printf("Concatenated string: %s\n", s3->content);
String *text = string_init("ababcabcacbab");
String *pattern = string_init("abcac");
int index = BF_Match(text, pattern);
if (index!= -1) {
printf("Pattern found at index: %d\n", index);
} else {
printf("Pattern not found\n");
}
free(s1->content);
free(s1);
free(s2->content);
free(s2);
free(s3->content);
free(s3);
free(text->content);
free(text);
free(pattern->content);
free(pattern);
return 0;
}
笔记:
- 在
main
函数中,首先创建和操作字符串,然后使用BF_Match
算法进行模式匹配。 - 注意在程序结束前,要释放为字符串内容和字符串结构体分配的内存,以避免内存泄漏。每个
string_init
和string_concat
创建的字符串都需要释放其内容指针和结构体指针。