字符函数和字符串函数的模拟实现及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;
}


相关文章
|
19天前
|
存储 算法
图解Kmp算法——配图详解(超级详细)
图解Kmp算法——配图详解(超级详细)
|
24天前
|
算法 测试技术 C#
【字典树】【KMP】【C++算法】3045统计前后缀下标对 II
【字典树】【KMP】【C++算法】3045统计前后缀下标对 II
|
24天前
|
算法
KMP算法 与 strstr()函数
KMP算法 与 strstr()函数
|
24天前
|
算法
【算法学习--字符串】(不含KMP算法)
【算法学习--字符串】(不含KMP算法)
|
2月前
|
机器学习/深度学习 算法 大数据
基于PyTorch对凸函数采用SGD算法优化实例(附源码)
基于PyTorch对凸函数采用SGD算法优化实例(附源码)
32 3
|
2月前
|
算法
白话 KMP 算法
白话 KMP 算法
14 2
|
14天前
|
机器学习/深度学习 人工智能 算法
基于DCT和扩频的音频水印嵌入提取算法matlab仿真
本文介绍了结合DCT和扩频技术的音频水印算法,用于在不降低音质的情况下嵌入版权信息。在matlab2022a中实现,算法利用DCT进行频域处理,通过扩频增强水印的隐蔽性和抗攻击性。核心程序展示了水印的嵌入与提取过程,包括DCT变换、水印扩频及反变换步骤。该方法有效且专业,未来研究将侧重于提高实用性和安全性。
|
1天前
|
存储 算法
m基于LDPC编译码的matlab误码率仿真,对比SP,MS,NMS以及OMS四种译码算法
MATLAB 2022a仿真实现了LDPC译码算法比较,包括Sum-Product (SP),Min-Sum (MS),Normalized Min-Sum (NMS)和Offset Min-Sum (OMS)。四种算法在不同通信场景有各自优势:SP最准确但计算复杂度高;MS计算复杂度最低但性能略逊;NMS通过归一化提升低SNR性能;OMS引入偏置优化高SNR表现。适用于资源有限或高性能需求的场景。提供的MATLAB代码用于仿真并绘制不同SNR下的误码率曲线。
15 3
|
4天前
|
算法 数据安全/隐私保护 计算机视觉
基于DCT变换的彩色图像双重水印嵌入和提取算法matlab仿真
**算法摘要:** - 图形展示:展示灰度与彩色图像水印应用,主辅水印嵌入。 - 软件环境:MATLAB 2022a。 - 算法原理:双重水印,转换至YCbCr/YIQ,仅影响亮度;图像分割为M×N块,DCT变换后嵌入水印。 - 流程概览:两步水印嵌入,每步对应不同图示表示。 - 核心代码未提供。
|
4天前
|
机器学习/深度学习 算法 数据可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
Matlab决策树、模糊C-均值聚类算法分析高校教师职称学历评分可视化
10 0