文章目录
1)题目
字符串查找
要求:
对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。
样例
输入: source = “source” , target = “target”
输出:-1
样例解释: 如果source里没有包含target的内容,返回-1
输入: source = “abcdabcdefg” ,target = “bcd”
输出: 1
样例解释: 如果source里包含target的内容,返回target在source里第一次出现的位置
2)思路
两种思路:
- 暴力匹配
- KMP
A、暴力匹配具体思路:
如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:
- 如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;
- 如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0。
B、KMP字符串查找算法
暴力匹配缺点在于每次匹配,他都要回溯到原来的位置重新开始,KMP字符串匹配算法可以利用之前已经部分匹配这个有效信息,保持i(源字符串的指针)不回溯,通过修改j (待匹配目标字符串)的位置,让指针尽量地移动到有效的位置。
KMP伪代码
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
- 如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
- 如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。即当匹配失败时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值(next 数组的每个值为最大对称长度的前缀后缀,然后整体右移一位,初值赋为-1)。
求前缀后缀最长公共元素长度以及next数组
next[j]的本质为:next[j] = k 代表p[j] 之前的模式串子串中,有长度为k 的相同前缀和后缀
将“最大长度值” 整体向右移动一位,然后初始值赋为-1,即可获得next 数组。
3)代码
(1)暴力匹配
#pragma once
#include "pch.h"
#include <iostream>
using namespace std;
#include <string>
class Solution {
public:
/**
* @param source:
* @param target:
* @return: return the index
*/
int strStr(string &source, string &target)