您的位置:首页 > 编程语言 > C语言/C++

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

2015-12-06 19:37 316 查看
题目:

给定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>
输出:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: