第四章 串

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

  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结构体分配内存。如果输入字符串指针strNULL,则字符串内容指针设为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的内容复制到新字符串中,再使用strcats2的内容连接到后面。
  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的起始位置开始逐个字符比较。
  • textpattern当前位置字符相等时,同时移动两个字符串的指针。
  • 若遇到不匹配的字符,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_initstring_concat创建的字符串都需要释放其内容指针和结构体指针。
相关推荐
艾莉丝努力练剑40 分钟前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
_殊途2 小时前
《Java HashMap底层原理全解析(源码+性能+面试)》
java·数据结构·算法
珊瑚里的鱼6 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
不知道叫什么呀6 小时前
【C】vector和array的区别
java·c语言·开发语言·aigc
秋说7 小时前
【PTA数据结构 | C语言版】顺序队列的3个操作
c语言·数据结构·算法
lifallen7 小时前
Kafka 时间轮深度解析:如何O(1)处理定时任务
java·数据结构·分布式·后端·算法·kafka
liupenglove7 小时前
自动驾驶数据仓库:时间片合并算法。
大数据·数据仓库·算法·elasticsearch·自动驾驶
python_tty8 小时前
排序算法(二):插入排序
算法·排序算法
然我8 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法
risc1234569 小时前
BKD 树(Block KD-Tree)Lucene
java·数据结构·lucene