力扣13. 字符串查找(普通匹配和KMS)

力扣13. 字符串查找

https://www.lintcode.com/problem/implement-strstr/description

对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1

两种方法:普通匹配和KMS

方法一:普通方法

思路:基础应用能力,O(n2),字符串匹配

只要中间有一个不匹配都不行;直到匹配到最后一个都相同时,才输出。

#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class Solution {
public:
	/**
	* @param source:
	* @param target:
	* @return: return the index
	*/
	int strStr(string &source, string &target)
	{
		// Write your code here
		if (source.size() == 0 && target.size() == 0)//鲁棒性
		{
			return 0;
		}
		if (target.size() == 0)//鲁棒性
		{
			return 0;
		}
		for (int i = 0; i < source.size(); i++)
		{
			if (source[i] == target[0])
			{
				for (int j = 0; j < target.size(); j++)
				{
					if (source[i + j] != target[j])break;//只要中间有一个不匹配都不行
					if (j == target.size() - 1)return i;//直到匹配到最后一个都相同时,才输出i
				}
			}
		}
		return -1;
	}
};

int main()
{
	Solution s;
	string source = "a";
	string target = "a";
	auto result = s.strStr(source, target);
	return 0;
}

方法二:KMP

有点小问题的KMP

不过思路是正确的

扫描二维码关注公众号,回复: 10662967 查看本文章
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;


class Solution {
public:
	/**
	* @param source:
	* @param target:
	* @return: return the index
	*/
	//
	int naive(string &source, string &target)
	{
		// Write your code here
		if (source.size() == 0 && target.size() == 0)//鲁棒性
		{
			return 0;
		}
		if (target.size() == 0)//鲁棒性
		{
			return 0;
		}
		int i = 0; int j = 0; int k = i;//从下标零开始计算,i记录主串位置,j记录
		while (i < source.size() && j < target.size())
		{
			if (source[i] == target[j])
			{
				i++;
				j++;
			}
			else
			{
				j = 0;
				k++;
				i = k;
			}
		}
		if (j >= target.size())
		{
			return k;
		}
		else
		{
			return -1;
		}
	}
	int KMP(string &source, string &target)
	{
		// Write your code here
		if (source.size() == 0 && target.size() == 0)//鲁棒性
		{
			return 0;
		}
		if (target.size() == 0)//鲁棒性
		{
			return 0;
		}
		int i = 0; int j = 0;//从下标零开始计算,i记录主串位置,j记录
		int next[20];
		//计算模式串的next数组
		getnext(next, target);
		while (i < source.size() && j <= target.size())
		{
			//j == 0,一种情况是模式串第一个字符target[0]开始识别,第二种情况是j按照next数组回退到next[0]时的情况
			//source[i] == target[j],如果相等继续比较下一个字符是否匹配
			if (j == 0 || source[i] == target[j])
			{
				i++;
				j++;
			}
			else
			{
				j = next[j];//i不回溯,j按照next数组回退
			}
		}
		if (j >= target.size())
		{
			int result123 = i - target.size();
			return (result123);
		}
		else
		{
			return -1;
		}
	}
	void getnext(int next[], string target)
	{
		int j = 0; int t = -1;//j代表字符的下标,t代表失配时下一步要移动的位置
		next[0] = -1;
		while (j < target.size())
		{
			if (t == -1 || target[j] == target[t])
			{
				next[j + 1] = t + 1;
				t++;
				j++;
			}
			else
			{
				t = next[t];
			}
		}
	}
};

int main()
{
	Solution s;
	string source = "abcdabcdefg";
	string target = "bcd";
	auto result = s.naive(source, target);
	auto resultKMP = s.KMP(source, target);
	return 0;
}
发布了23 篇原创文章 · 获赞 0 · 访问量 137

猜你喜欢

转载自blog.csdn.net/qq_35683407/article/details/105401337