網(wǎng)站首頁 編程語言 正文
strstr函數(shù)介紹
C語言提供了字符串匹配函數(shù) strstr 函數(shù),請看文檔簡介。
這個函數(shù)是用來匹配 str2 是否包含在 str1 字符串中,如果匹配成功,則返回指向str1中第一個出現(xiàn)的str2的指針,如果str2不是str1的一部分,則返回空指針。
我們不妨舉例說明,請看下面代碼,調(diào)用 strstr 函數(shù)需要引入string.h頭文件,我們發(fā)現(xiàn),s1字符串中可以找到s2字符串,那么就返回s1中s2的第一個字符的地址,s1字符串并沒有s3,所以返回空指針。
#include<stdio.h>
#include<string.h>
int main(){
char* s1 = "abcdefgh";
char* s2 = "def";
char* s3 = "dee";
printf("%s\n",strstr(s1,s2)); //defgh
printf("%s\n",strstr(s1,s3)); //(null)
return 0;
}
BF算法介紹
BF算法,即暴力(Brute Force)算法,BF算法的思想就是str1的第一個字符與str2的第一個字符進行匹配,若相等,則繼續(xù)比較str1的第二個字符和 str2的第二個字符;若不相等,則比較str1的第二個字符和str2的第一個字符,依次比較下去,直到得出最后的匹配結(jié)果。
BF算法模擬實現(xiàn)strstr函數(shù)
用BF算法實現(xiàn) strstr 函數(shù)的思路就是遍歷整個 str1,在內(nèi)層循環(huán)進行判斷,如果str1 和 str2 對應(yīng)的字符相等且比較的字符在 str2 長度范圍之內(nèi), 那么就比較下一位,當這次循環(huán)結(jié)束,此時只有兩種情況,第一種是比較的字符等于 str2 的長度,那么就代表找到了,返回 str2 在 str1 第一個字符地址即可,至于為什么是 str1 + i - j,請朋友們思考一下就明白了。第二種情況是某個字符之間不匹配,那么 str1 下次匹配的位置為前一個字符位置 + 1,str2 又回到第一個字符開始匹配。直到整個 str1 超出了匹配的范圍,代表找不到整個字符串 str2,故返回NULL。
char* my_strstr(char* str1, char* str2){
assert(str1 && str2);
int slen = strlen(str1);
int sublen = strlen(str2);
int i = 0;
int j = 0;
int count = 0;
while(i < slen){
while(str1[i] == str2[j] && j < sublen){
++i;
++j;
}
if(j >= sublen){
return str1 + i - j;
}
++count;
i = count;
j = 0;
}
return NULL;
}
KMP算法介紹
KMP算法是一種改進的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人們稱它為克努特—莫里斯—普拉特操作(簡稱KMP算法)。KMP算法的核心是利用匹配失敗后的信息,盡量減少模式串(str2)與主串(str1)的匹配次數(shù)以達到快速匹配的目的。具體實現(xiàn)就是通過一個next數(shù)組實現(xiàn),數(shù)組本身包含了模式串的局部匹配信息。
KMP算法與BF算法的區(qū)別是:主串不會回退,模式串每次也不一定回退到第一個位置上。
具體算法思想可參考:KMP算法講解
KMP算法模擬實現(xiàn)strstr函數(shù)
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
void get_next(int* next, char* sub){
int len = strlen(sub);
next[0] = -1;
next[1] = 0;
int i = 2;
int k = 0;
while(i < len){
if(k == -1 || sub[i-1] == sub[k]){
next[i] = ++k;
++i;
}else{
k = next[k];
}
}
}
char* my_strstr(char *str1, char * str2){
assert(str1 && str2);
int slen = strlen(str1);
int sublen = strlen(str2);
int* next = (int*)malloc(sizeof(int)*sublen);
assert(next);
get_next(next,str2);
int i = 0;
int j = 0;
while(i < slen && j < sublen){
if(j == -1 || str1[i] == str2[j]){
++i;
++j;
}else{
j = next[j];
}
}
if(i >= sublen){
return str1 + i - j;
}else{
return NULL;
}
}
原文鏈接:https://blog.csdn.net/weixin_45959662/article/details/125745125
相關(guān)推薦
- 2022-10-30 Go中的錯誤和異常處理最佳實踐方法_Golang
- 2022-02-23 C#使用log4net記錄日志_C#教程
- 2022-04-11 python文件讀寫操作小結(jié)_python
- 2022-09-29 Python模塊域名dnspython解析_python
- 2022-04-28 Python的線程使用隊列Queue來改造轉(zhuǎn)賬場景_python
- 2022-05-11 批量導入模板數(shù)據(jù)的時候遇到的一些關(guān)于多線程的問題
- 2022-12-24 Android自定義View實現(xiàn)繪制水波浪溫度刻度表_Android
- 2022-12-11 C++?Boost?Tokenizer使用詳細講解_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支