【问题标题】: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)。

标签: c++ string algorithm comparison rotation


【解决方案1】:
  1. 将给定字符串与给定字符串连接。

  2. 在拼接字符串中搜索目标字符串。

例子:

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

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多