字符函数和字符串函数的模拟实现及KMP算法(上)

简介: 字符函数和字符串函数的模拟实现及KMP算法

求字符串长度

strlen

函数功能

求一个字符串的长度,计算的是’\0’之前出现的字符个数

函数参数

size_t strlen( const char *string );
# size_t 是函数的返回类型
# char* string 是函数参数

模拟实现

size_t my_strlen(char *str)
{
  int count = 0;
  while (*str != '\0')
  {
    count++;
    str++;
  }
  return count;
}

注意事项

1.strlen的结束标志是’\0’,因此要求传给strlen的参数必须带’\0’,否则strlen的结果就是随机值。(因为strlen会一直向后访问,直到找到’\0’。可以说是一个大情种了(手动滑稽))。

2.strlen的返回值是无符号整形,如果用两个strlen相减的话得到的结果始终是非负数。

长度不受限制的字符串函数

strcpy

函数功能

字符串拷贝,将一个字符串的内容拷贝到另一个字符串中(包括’\0’)

函数参数

char* strcpy(char * destination, const char * source );
# char* 是函数的返回值,返回的是目标空间的起始地址
# source 是要拷贝的字符串
# destination 是目标空间

模拟实现

char* my_strcpy(char* dest, char* src)
{
    assert(dest&&src);//assert断言,保证dest和src不为空指针,头文件为#include<assert.h>
  char* ret = dest;//函数要求返回目标空间的起始地址
  while (*dest++ = *src++)
  {
    ;
  }
  return ret;
}

while循环里的语句是将src指向的内容拷贝到dest当前指向的位置,再用拷贝的结果来作为判断,最后对两个指针进行自增操作。

注意事项

源字符串必须要是以"\0"结束

目标空间要足够大

目标空间必须可修改。

strcat

函数功能

字符串追加,在一个字符串的末尾追加另一个字符串(包含’\0’)

函数参数

char * strcat ( char * destination, const char * source );
# char* 是函数的返回值,返回的是目标空间的起始地址
# source 是要追加的字符串
# destination 是目标空间

模拟实现

char* my_strcat(char* dest, char* src)
{
    assert(dest&&src);
  char* ret = dest;
  //先找到dest的末尾,再字符串拷贝
  while (*dest != '\0')
  {
    dest++;
  }
  while (*dest++ = *src++)
  {
    ;
  }
  return ret;
}

注意事项

1.源字符串必须以’\0’结束

2.目标空间必须足够大,能够放下追加后的字符

3.目标空间必须是可修改的

4.strcat不能自己给自己追加。(因为自己给自己追加会覆盖掉末尾的’\0’,导致死循环)

strcmp

函数功能

字符串比较,比较两个字符串大小,如果相等则往后移,直到’\0’结束

函数参数

int strcmp ( const char * str1, const char * str2 );
# int 函数返回值
# char* str1  char* str2 用于比较的两个字符串
#返回值
>0 : str1 大于 str2;
=0 : str1 等于 str2;
<0 : str1 小于 str2

模拟实现

int my_strcmp(const char* str1, const char* str2)
{
  assert(str1 && str2);
  //如果相等就往后比较
  while (*str1 != '\0' && *str2 != '\0' && *str1 == *str2)
  {
    //相等的情况在这里,如果进来循环并且有一个为\0,那就说明两个字符串都到结尾了
    if (*str1 == '\0')
      return 0;
    str1++;
    str2++;
  }
  /*if (*str1 > *str2)
    return 1;
  else
    return -1;*/
  return(*str1 - *str2);//第一个字符串大于第二个字符串,则返回大于0的数字,第一个字符串小于第二个字符串,则返回小于0的数字。既然它们不相等,那么直接作差就能得到大小
}

注意事项

字符在内存中是以ASCII码值存储的,因此比较的也是每一对字符的ASCII码值

长度受限制的字符串函数

由于strcpy,strcat,strcmp等字符串函数不受长度的限制,容易造成越界的问题存在安全隐患。因此C语言还给我们提供了另外几种相对安全的字符串函数,即strncpy,strncat,strncmp。它们比原字符串函数多了一个参数,这个参数是用于指定操作的字节数。因为受到长度的限制,不会无脑梭哈,因此也相对更安全。(不是绝对安全,毕竟我要写bug谁也拦不住(斜眼笑))。

strncpy

函数功能

字符串拷贝,把一个字符串中指定的字节数的内容拷贝到另一个字符串中

函数参数

char * strncpy ( char * destination, const char * source, size_t num );
# char* 是函数的返回值,返回的是目标空间的起始地址
# source 是要拷贝的字符串
# destination 是目标空间
# num 是要拷贝的字节数

模拟实现

char* my_strncpy(char* dest, const char* src, size_t num)
{
  assert(dest && src);
  char* ret = dest;  //记录目标空间的起始地址
  while (num--)
  {
    *dest = *src;
    if (*dest == '\0')  //如果*dest为0,说明将src的结束字符赋给了dest,这种情况下源字符串的长度小于num
    {
      while (num--)
      {
        //如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。(与库函数的实现方式保持一致)
        *dest++ = 0;
      }
      break;
    }
    dest++;
    src++;
  }
  *dest = '\0';  //在dest的末尾补上结束字符
  return ret;
}

注意事项

可以看到,如果源字符串中的内容不够num个,会把用’\0’来补足。

strncat

函数功能

字符串追加,将一个字符串中num个字节的内容拷贝到另一个字符串的末尾,并在末尾补充’\0’。

函数参数

char * strncat ( char * destination, const char * source, size_t num );
# char* 是函数的返回值,返回的是目标空间的起始地址
# source 是要追加的字符串
# destination 是目标空间
# num 是要追加的字节数

模拟实现

char* my_strncat(char* dest, const char* src, size_t num)
{
  assert(dest && src);
  char* ret = dest;  //记录目标空间的起始地址
  //找到dest末尾
  while (*dest != '\0')
  {
    dest++;
  }
  //strncpy
  while (num--)
  {
    *dest = *src;
    if (*dest == '\0')  //如果*dest为0,说明将src的结束字符赋给了dest,这种情况下源字符串的长度小于num
    {
      //如果源字字符串的长度小于num,则只复制到终止空字符的内容。(与库函数的实现方式保持一致)
      return ret; //直接返回
    }
    dest++;
    src++;
  }
  *dest = '\0';  //则在dest的末尾补上结束字符
  return ret;
}

注意事项

如果源字符串的内容少于num个字节,也只复制到终止空字符的内容,也就是说并不会再去补’\0’。

strncmp

函数功能

字符串比较,比较两个字符串中前num个字节内容的大小

函数参数

int strncmp ( const char * str1, const char * str2, size_t num );
# int 函数返回值
# char* str1  char* str2 用于比较的两个字符串
# num 要比较的字节数
#函数返回值
>0 : str1 大于 str2;
=0 : str1 等于 str2;
<0 : str1 小于 str2

模拟实现

int my_strncmp(const char* str1, const char* str2, int num)
{
  assert(str1 && str2);
  for(int i=0;i<num;i++)//库中使用的是for循环,因此我们也用for循环
  {
    if (*str1 == *str2)
    {
      str1++; 
      str2++;
    }
    else
    {
      return(*str1 - *str2);
    }
  }
  return 0;
}

注意事项

比较的是每一对字符中的ASCII码值。

对前num个字节逐一比较,除非遇到’\0’或者不相等字符。

字符串查找函数

strstr

函数功能

查找子串,在一个字符串中查找是否包含该子串

函数参数

char * strstr ( const char *str1, const char * str2); 
# char* 函数返回值,返回字符串中子串的起始地址,若找不到,则返回NULL;
# char* str1 要搜索的字符串;
# char* str2 子串

模拟实现

分析:

代码实现:

char* my_strstr(const char* str1, const char* str2)
{
  assert(str1 && str2);
  //根据分析,至少要三个指针
  const char* s1 = str1;
  const char* s2 = str2;
  const char* p = str1;
  while (*p)
  {
    s1 = p;//
    s2 = str2;
    while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
    {
      s1++;
      s2++;
    }
    if (*s2 == '\0')
      return (char*)p;
    p++;//p记录的是上次匹配的起始位置,匹配失败要从上次的位置的下一个位置开始匹配
  }
  return NULL;
}


相关文章
|
2月前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
53 0
|
23天前
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
125 67
|
3月前
|
XML JavaScript 前端开发
学习react基础(1)_虚拟dom、diff算法、函数和class创建组件
本文介绍了React的核心概念,包括虚拟DOM、Diff算法以及如何通过函数和类创建React组件。
36 3
|
2月前
|
算法
第四章 KMP算法理论基础
第四章 KMP算法理论基础
22 0
|
2月前
|
算法
KMP算法
KMP算法
38 0
|
4月前
|
算法 C++
A : DS串应用–KMP算法
这篇文章提供了KMP算法的C++实现,包括计算模式串的next数组和在主串中查找模式串位置的函数,用于演示KMP算法的基本应用。
|
4月前
|
算法
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
【Azure Developer】完成算法第4版书中,第一节基础编码中的数组函数 histogrm()
|
4月前
|
算法
KMP算法
KMP算法
36 0
|
17天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
3天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。