旋转字符串的判断——KMP实现 (C++)

题目:

         给定2个字符串srt1和str2,实现一个算法判断其是否互为旋转字符串。

         注:

                  比如字符串”ABCDE” 那么”BCDEA” “CDEAB” “DEABC” “EABCD”都是其旋转字符串。


思路:

         这里我们判断str2是否是str1的旋转字符串。

                  ①.  如果str1和str2的长度都不相等,那么肯定返回false,不需要执行下面的操作。

                  ② . str1和str2的长度相等

                          我们可以按照旋转字符串的定义,对str2进行旋转移位,并判断移位后的字符串是否与str1相等。这样最多需要执行n-1次这样的操作。【n是给定字符串的长度】

                          下面给出另外一种O(N)复杂度的算法,基于KMP的字符串模式匹配。

                                    举例说明:对于str1 = “ABCD” str2 = “BCDA” 

                                            那么 新生成一个新字符串str3 = str1 + str1; 可以看到:

                                                    str3 = “ABCDABCD” 这其中包含了所有可能的旋转字符串 即: BCDA CDAB DABC

                                            因此 接下来的操作就是判断str3中是否str2这样的子串,属于字符串匹配问题。可以由KMP算法求解。

         贴代码:

<span style="font-size:14px;">#include <iostream>
#include <string>
#include <vector>

using namespace std;

bool chkRotation(const string A, const int lena, const string B, const int lenb);
void nextArr(const string str, vector<int> &v);
int KMP(const string str, const string mode);

bool chkRotation(const string A, const int lena, const string B, const int lenb) 
{
	return (KMP(A + A, B) != -1);
}

// 求next数组v
void nextArr(const string str, vector<int> &v)
{
	// 字符串长度为1 直接返回 [-1]
	if (str.length() == 1)
	{
		v[0] = -1;
		return;
	}

	// 前两个字符的next值分别为 -1 0
	v[0] = -1;
	v[1] = 0;

	unsigned int pos = 2, cnt = 0;

	while(pos < v.size())
	{
		if (str[pos - 1] == str[cnt])
		{
			v[pos++] = ++cnt;
		}
		else if(cnt > 0)
		{
			cnt = v[cnt];
		}
		else
		{
			v[pos++] = 0;
		}
	}
}

int KMP(const string str, const string mode)
{
	// 异常检查
	if (str.empty() || mode.empty() || mode.length() < 1 || str.length() < mode.length())
	{
		return -1;
	}

	// next数组长度只与模式串有关
	vector<int> next(mode.length());
	// 获取next数组
	nextArr(mode, next);

	unsigned int idx = 0, modeIdx = 0;

	while(idx < str.length() && modeIdx < mode.length())
	{
		if (str[idx] == mode[modeIdx])
		{
			idx++;
			modeIdx++;
		}
		else if (next[modeIdx] == -1)
		{
			idx++;
		}
		else
		{
			modeIdx = next[modeIdx];
		}
	}

	return ((modeIdx == mode.length()) ? (idx - modeIdx) : -1);
}

int main(void)
{
	string s1 = "1234", s2 = "2341";
	int len1 = s1.length(), len2 = s2.length();

	if (chkRotation(s1, len1, s2, len2))
	{
		cout<<"YES : s1 and s2 are rotated string"<<endl;
	}
	else
	{
		cout<<"NO : s1 and s2 are not rotated string"<<endl;
	}

	return 0;
}</span>

输出:

《旋转字符串的判断——KMP实现 (C++)》

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/u013575812/article/details/50197409
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞