第四章 串

一、字符串的存储结构与基本运算

  1. 字符串结构体定义(动态分配内存方式)
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 字符串结构体
typedef struct String {
    char *content;
    int length;
} String;
  1. 字符串初始化函数
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将输入字符串复制到新分配的内存中。
  1. 求字符串长度函数
c 复制代码
// 获取字符串长度
int string_length(String *s) {
    return s->length;
}

笔记:直接返回字符串结构体中的长度成员。

  1. 字符串连接函数
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的内容连接到后面。
  1. 字符串比较函数
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创建的字符串都需要释放其内容指针和结构体指针。
相关推荐
longlongzihan5 小时前
LeetCode 17电话号码的字母组合:回溯算法(DFS)详解
c++·算法·leetcode·深度优先
封印师请假去地球钓鱼5 小时前
边解边变的问题:从“决策依赖“一词出发
人工智能·算法
今晚打老虎6 小时前
c++之提高A(前缀和)(第三课)
数据结构·c++·算法
不会就选b7 小时前
算法日常・每日刷题--<贪心>26
数据结构·算法
铅笔小新z8 小时前
【C语言】操作符
c语言
hetao17338379 小时前
2026-09-29 hetao1733837 的刷题记录
c++·算法
by209999 小时前
从 malloc/free 到 new/delete:真正理解 C++ 中的内存管理与对象生命周期
c语言·c++·经验分享·动态内存管理
额额额对了9 小时前
SPI通信
linux·c语言·汇编·单片机·嵌入式硬件·arm
欣欣之王来了9 小时前
AI合规专项:AI算法透明度的合规要求
人工智能·算法
wzdark9 小时前
分块思想在算法优化中的实践与应用4
算法