第四章 串

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

  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创建的字符串都需要释放其内容指针和结构体指针。
相关推荐
£suPerpanda6 分钟前
牛客周赛 Round65 补题DEF
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
ao_lang10 分钟前
剑指offer第五天
python·算法·cpp
付宇轩12 分钟前
leetcode 173.二叉搜索树迭代器
算法·leetcode·职场和发展
L_cl12 分钟前
数据结构与算法——Java实现 54.力扣1008题——前序遍历构造二叉搜索树
算法·leetcode
KeithTsui13 分钟前
ZFC in LEAN 之 前集的等价关系(Equivalence on Pre-set)详解
开发语言·其他·算法·binder·swift
玛卡巴卡(努力学习版)24 分钟前
矩阵特殊打印方式
c++·算法·矩阵
佚明zj29 分钟前
【点云网络】 pointnet 和 pointnet++
算法
暴怒香菜统治世界29 分钟前
数据结构--二叉树_链式(下)
c语言·开发语言·数据结构·算法·链表
飞滕人生TYF31 分钟前
判断图中是否存在环
算法·深度优先