搜索子字符串函数 strstr() 的标准库实现

Night gathers, and now my watch begins.
It shall not end until my death.
I shall take no wife, hold no lands, father no children.
I shall wear no crowns and win no glory.
I shall live and die at my post.
I am the sword in the darkness.
I am the watcher on the walls
.I am the fire that burns against the cold, the light that wakes the sleepers, the shield that guards the realms of men.
I pledge my life and honor to the Night’s Watch, for this night, and all the nights to come.
长夜将至,我从今开始守望,至死方休。
我将不娶妻、不封地、不生子。
我将不戴宝冠,不争荣宠。
我将尽忠职守,生死於斯。
我是黑暗中的利剑,长城中的守卫。
我是抵御寒冷的烈焰,破晓时分的光线,唤醒死者的号角,守护王国的铁卫。
我将生命与荣耀献给守夜人,
今夜如此,夜夜皆然。
– 《权力的游戏》守夜人宣言

最近经常使用到在某个字符串中搜索某个字符串的功能,本来还想着如何去实现,后来发现 C 语言的标准库函数就有提供,借鉴(抄袭 )不香吗?

下面就来一波源码分析。

源码下载地址:The GNU C Library (glibc) 或者 µ C l i b c

首先这个函数的作用是搜索子字符串,如果使用标准库函数,那么就得包含头文件 <string.h>
看一下函数原型:

char *strstr(const char *s1, const char *s2);

也就是在 s1 中搜索s2 字符串出现的位置。
返回指针,此指针指向 s1 字符串中的字符第一次出现在 s2 字符串中的位置。如果没有发现匹配,就返回空指针。

下面看一下该函数源码的实现:

char *strstr(const char *s1, const char *s2) //使用const可以保证函数不会修改指针所指向内容  
{
    int s1_len, s2_len; 
    s2_len = strlen(s2);
    if (!s2_len) 	//若S2字符串为空,返回空指针
        return (char *)s1;
    
	s1_len = strlen(s1);
    while (s1_len >= s2_len) 
   {    
   		s1_len--;        
		if (!memcmp(s1, s2, s2_len)) //将s1中的s2_len长度大小的部分与s2比较,看是否相等
	    	return (char *)s1;        
		s1++;  //字符串指针不断后移,要不找到,要不结束
    }   
     
    return NULL;
}

上面的函数调用了 memcmp() 函数,本着源码分析到底的想法,我们再来看看这个函数是如何实现的。

/**
* memcmp - Compare two areas of memory
* @cs: One area of memory
* @ct: Another area of memory
* @count: The size of the area.
*/
int memcmp(const void * cs,const void * ct,size_t count)
{
	const unsigned char *su1, *su2;
	int res = 0;

	for ( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)//一个个字符比较
	{
		if ((res = *su1 - *su2) != 0) //若有一个字符不同则立即结束比较操作
    		break;
	}
	return res;
}

我们可以看到,由于为了实现简单,C标准库的 strstr() 的运行效率并不是很高效,时间复杂度达到了 O(n^2),不过好在空间复杂度只有 O(1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值