字符串匹配的三种方法

  字符串匹配,实现c++ strstr()函数

1.蛮力法

 1 int strStr(string haystack, string needle) {
 2
 3         int i, hSize = haystack.size(), nSize = needle.size();
 4         if(hSize < nSize)
 5             return -1;
 6         if(nSize == 0)
 7             return 0;
 8         for(i = 0; i <= hSize - nSize && haystack.substr(i, nSize) != needle; ++i);
 9
10         return i <= hSize - nSize ? i : -1;
11     }

2.Robin Karp

  具体说明参考维基百科:https://en.wikipedia.org/wiki/Rabin–Karp_algorithm

 1 char hash(const string& str)
 2     {
 3         char all = 0;
 4         for(auto c : str)
 5             all ^= c;
 6         return all;
 7     }
 8
 9 //选定一个hash函数,对字符串hash,hash值不同一定是不同字符串
10     //由于hash值可能有冲突 所以hash值相同的字符并不一定相同 需要逐个字符再比较
11     //hash函数可以自己写,也可以用std::hash<string>
12     int strStr(string haystack, string needle) {
13
14         int i, hSize = haystack.size(), nSize = needle.size();
15         if(hSize < nSize)
16             return -1;
17         if(nSize == 0)
18             return 0;
19         //或者使用std::hash
20         //std::hash<string> hash;
21         char target = hash(needle);
22         for(i = 0; i <= hSize - nSize; ++i)
23         {
24             if(hash(haystack.substr(i,nSize)) == target && haystack.substr(i,nSize) == needle)
25                 break;
26         }
27
28         return i <= hSize - nSize ? i : -1;
29     }

3.kmp

  具体说明参考维基百科:https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm

 1 vector<int> buildNextArray(const string& s)
 2     {
 3         vector<int> next(s.size());
 4         int i = 2, j = 0;
 5         next[0] = -1;
 6         if(s.size() > 1)
 7             next[1] = 0;
 8         while(i < s.size())
 9         {
10             if(s[i-1] == s[j])
11                 next[i++] = ++j;
12             else if(j > 0)
13                 j = next[j];
14             else
15                 next[i++] = 0;
16         }
17         return next;
18     }
19
20 int strStr(string haystack, string needle) {
21
22         int start = 0, i = 0, hSize = haystack.size(), nSize = needle.size();
23         if(hSize < nSize)
24             return -1;
25         if(nSize == 0)
26             return 0;
27         //kmp算法
28         vector<int> next = buildNextArray(needle);
29         while(start <= hSize - nSize)
30         {
31             if(haystack[start + i] == needle[i])
32             {
33                 if(++i == nSize)
34                     return start;
35             }
36             else
37             {
38                 start = start + i - next[i];
39                 i = i > 0 ? next[i] : 0;
40             }
41         }
42
43         return -1;
44     }
时间: 2024-10-13 22:19:23

字符串匹配的三种方法的相关文章

字符串匹配的三种算法

下面将介绍三种有关字符串匹配的算法,一种是朴素的匹配算法,时间复杂度为O(mn),也就是暴力求解.这种方法比较简单,容易实现.一种是KMP算法,时间复杂度为O(m+n),该算法的主要任务是求模式串的next数组.另外还有一种对KMP算法的改进,主要是求nextval数组. 第一种朴素的匹配算法: int index(char str[], char subStr[]) { int i = 0, j = 0,index = 0; while (str[i] != '\0' && subStr

防止sql注入的三种方法

常用的避免SQL注入的三种方法 一,存储过程 在学习数据库视频的时候接触过,它是存储在数据库中的一些事先编译好的指令.在用的时候不用重新编写,直接调用就好了.所以,使用它可以大大提高程序的执行效率. 那么,如果创建一个存储程序并使用它呢?这是我们今天要解决的问题 1.创建过程 可编程性--下拉菜单--存储过程--右键--查询菜单--指定模板参数的值--新建查询--输入语句--查询菜单中的分析检查语法是否正确--执行 2.具体创建语法 在创建存储程序时,为了应对各种变换的数据,通常会涉及到带参数的

Java中获取键盘输入值的三种方法

Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值的现成函数!Java没有提供这样的函数也不代表遇到这种情况我们就束手无策,请你看以下三种解决方法吧: 以下将列出几种方法: 方法一:从控制台接收一个字符,然后将其打印出来 import java.io.*; public static void main(String [] args) throws

[mysql]三种方法为root账户指定密码

前言:前段时间把mysql安装后一直没管它,当时就在奇怪为什么mysql登陆不要密码,原来一直用的超用户账户登陆的(简称超级用户) 其实只怪自己太无知,之前一直用的phpbydamin进行的数据库的可视化管理,哪里知道这么详细呢? 本文原文来源mysql官方文档5.1 正文:最开始可以使用SELECT User.Password FROM mysql.user查询mysql数据库root账户的密码 你可以用几种方法为root账户指定密码.以下介绍了三种方法: ·         使用SET PA

NGUI制作字体的三种方法

主要参考两篇博文: (1).NGUI制作字体的三种方法 (2).使用位图字体工具BMFont从图片生成自定义字体 1.BMFont下载地址 http://www.angelcode.com/products/bmfont/ 2.BMFont使用方法 http://momowing.diandian.com/post/2013-01-24/40046239211 首先打开Font Settings,选择要制作的字体.可以从Font列表中选择一种字体,也可以通过Add font files导入一个t

Number类为数字到字符串的类型转换场景定义三种方法

toFixed()根据小数点后的指定位数将数字转换为字符串,它从不使用指数计数法: toExponential()使用指数计数法将数字转换为指数形式的字符串,其中小数点前只有一位,小数点后的位数则由参数指定(也就是说有效数字位数比指定的位数要多一位): toPrecision()根据指定的有效数字位数将数字转换成字符串,如果有效数字的位数少于数字整数部分的位数,则转换成指数形式. 这三种方法都会适当的进行四舍五入或填充0. 例: var n = 123456.789; n.toFixed(0);

VBS中解决路径带空格的三种方法

vbs中,如果需要运行的程序中带有空格,按照通常的方式往往会提示错误,其实有两种形式不同的解决方法: 在应用程序前后分别加三个双引号,代码如下: [c-sharp] view plaincopyprint? Set wshell=CreateObject("WScript.Shell") wshell.Run  """C:/Program Files/360/360se/360se.exe""",5,True Set wshe

三种方法保留小数位数

js代码部分为 var PI=3.1415192;var str=PI+""; //因为数字没法进行字符操作,所以需要先转换:var index=str.indexOf(".");//返回当前的字符的点的位置console.log(index); //1console.log(str.substr(0,index+3)); //3.14 //合并后的第一种写法console.log(str.substr(0,str.indexOf(".")+3)

实例365(8)---------三种方法将字符串格式化为日期

一:DateTime.ParseExact方式,截图 二:代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ConvertToString { public