如何检查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::strings(在一般情况下,元素甚至可能不是字符)并且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个字符串是不是相互旋转?的主要内容,如果未能解决你的问题,请参考以下文章

相互检查字符串(Anagrams)

vb 检查 2 个字符串是不是有 2 个不相等的字符

如何检查字符串是不是至少有 1 个字母字符? [复制]

检查2个坐标是不是在同一个城市

Python - 比较 2 个单词并检查它们是不是是字谜

如何检查 Swift 字符串是不是只包含某些字符?