如何检查2个字符串是不是相互旋转?
Posted
技术标签:
【中文标题】如何检查2个字符串是不是相互旋转?【英文标题】:how to check whether 2 strings are rotations to each other ?如何检查2个字符串是否相互旋转? 【发布时间】:2011-10-25 20:59:20 【问题描述】:给定两个字符串,设计一个函数来检查它们是否相互旋转而不对其进行任何更改?返回值是布尔值。
例如 ABCD、ABDC,它们不是旋转。返回错误
ABCD、CDAB 或 DABC 是旋转。返回真。
我的解决方案:
将其中一个向右或向左移动一个位置,然后在每次迭代时比较它们。 如果它们在所有迭代中都不相等,则返回 false。否则,返回真。
是 O(n)。还有其他更有效的解决方案吗? 如果它们的内容无法更改怎么办?
谢谢
【问题讨论】:
我认为您需要检查您的 O() 表示法。这不是 O(n)。 首先,正如@Chriszuma 指出的那样,您的算法不是 O(n)。其次,你不可能比 O(n) 做得更好,因为这只是 检查 字符串所必需的。 (很明显,如果不检查字符串,你就无法解决这个问题。)我严重怀疑你甚至可以为这个问题实现 O(n)。 【参考方案1】:将给定字符串与给定字符串连接。
在拼接字符串中搜索目标字符串。
例子:
Given = CDAB
After step 1, Concatenated = CDABCDAB
After step 2, Success CDABCDAB
^^^^
【讨论】:
你的意思不是“将给定的字符串与自身连接”吗? “不对其进行任何更改” @Branko -- 然后先复制一份。 第 0 步:确保字符串大小相同。 @ArunSaha 这是不正确的:如果Given = ABCD
而您正在搜索ABCDABCD
怎么办?【参考方案2】:
与其移动其中一个,使用两个索引变量可能更有效。每次从 0 开始,在每个可能的位置(0 到 N-1)开始另一个,然后递增 mod N。
【讨论】:
【参考方案3】:如果无法修改字符串,只需将 string1 的第一个字符与 string2 的每个字符进行比较即可。当你得到匹配时,将 string1 的第二个字符与 string2 的下一个字符进行比较,以此类推。
伪代码:
len = strlen(string1);
len2 = strlen(string2);
if( len != len2 )
printf("Nope.");
for( int i2=0; i2 < len; i2++ )
for( int i1=0; i1<len; i1++ )
if( string1[i1] != string2[(i2+i1)%len] )
break;
if( i1 == len )
print("Yup.");
break;
【讨论】:
比 O(n) 差 O(n^2)。 您还可以调整 Boyer-Moore 或 Knuth-Morris-Pratt 以在“包装的”s2 中搜索 s1。我怀疑对于长字符串,这在实践中会非常快,即使最坏的情况仍然是 O(n^2) 伙计……Boyer、Moore、Knuth、Morris 和 Pratt 都是相当聪明的家伙。【参考方案4】:一个简单的方法是:
(s1+s1).find(s2) != string::npos && s1.size() == s2.size();
【讨论】:
这是不正确的:s1="a"
, s2="aa"
会给你一个匹配。
当然。这样做的问题是这些可能不一定是std::string
s(在一般情况下,元素甚至可能不是字符)并且size()
可能在恒定时间内不可用。此外,您正在创建一个新字符串 - 问题的精神似乎是“到位”(不仅仅是“不修改原始字符串”)。
@Branko,标签具体是 c++ 和字符串。我要使用 std::string。就 size() 的 O(1) 而言;该标准为 O(1) 指定了一个“应该”,因为我们使用了燧石和火种,所以我会做出有根据的猜测,大多数实现都是这样做的。如果创建额外的字符串对于 OP 来说太昂贵了,那么这不是要走的路。
string
标签的描述说:“字符串是零个或多个字符的序列,常用来表示文本。”。这可能是char*
(当然没有恒定时间size()
)。我设法将comparison
标签误读为competition
,所以我认为性能是绝对必须的。有时我会过分热心,抱歉;)
@Captain Giraffe,您的解决方案看起来很简单,但由于 find(),它仍然是 O(n)。【参考方案5】:
#include <iostream>
#include <cstring>
#include<string>
using namespace std;
void CompareString(string, string, int);
int ComputeStringLength(string str);
int main()
string str = ""; string str1 = ""; int len = 0, len1 = 0;
cout << "\nenter string ";
cin >> str;
cout << "\nenter string 2 to compare:- ";
cin >> str1;
len = ComputeStringLength(str);
len1 = ComputeStringLength(str1);
if (len == len1)
CompareString(str, str1, len);
else
cout << "rotation not possible";
getchar();
return 0;
int ComputeStringLength(string str)
int len = 0;
for (int i = 0; str[i] != '\0'; i++)
len++;
return len;
void CompareString(string str, string str1, int n)
int index = 0, flag = 0, curr_index = 0, count1 = 0, flagj = 0;
for (int i = 0; i<n; i++)
for (int j = flagj; j<n; j++)
if (str[i] == str1[j])
index = j;
flagj =j;
count1++;
flag++;
if (flag == 1)
curr_index = index;
break;
int temp = count1;
if (count1 != n)
if (curr_index>=0)
int k = 0;
for (int i = n - 1; i>n - curr_index - 1; i--)
if (str[i] == str1[k])
temp++;
k++;
if (temp == n)
cout << "\n\nstring is same after rotation";
else
cout << "\n\nstring is not same after rotation";
else
cout << "\n\nstring is same after rotation";
https://dsconceptuals.blogspot.in/2016/10/a-program-to-check-if-strings-are.html
【讨论】:
以上是关于如何检查2个字符串是不是相互旋转?的主要内容,如果未能解决你的问题,请参考以下文章