web-dev-qa-db-fra.com

Question de l’entrevue: Vérifiez si une chaîne est une rotation de l’autre chaîne

Un de mes amis a posé la question suivante aujourd'hui lors d'un entretien à un poste de développeur de logiciels:

Étant donné deux chaînes s1 et s2, comment vérifier si s1 est une version tournée de s2?

Exemple:

Si s1 = "stackoverflow", voici ci-dessous certaines de ses versions avec rotation:

"tackoverflows"
"ackoverflowst"
"overflowstack"

"stackoverflwo" est pas une version tournée.

La réponse qu'il a donnée était:

Prenez s2 et trouvez le préfixe le plus long, qui est une sous-chaîne de s1, qui vous donnera le point de rotation. Une fois que vous avez trouvé ce point, séparez s2 à cet endroit pour obtenir s2a et s2b, puis vérifiez si concatenate(s2a,s2b) == s1

Cela semble être une bonne solution pour moi et mon ami. Mais l'intervieweur a pensé autrement. Il a demandé une solution plus simple. Aidez-moi s'il vous plaît en disant comment vous feriez cela dans Java/C/C++?

Merci d'avance.

235
Webdev

Vérifiez d’abord que s1 et s2 ont la même longueur. Puis vérifiez si s2 est une sous-chaîne de s1 concaténée avec s1:

algorithm checkRotation(string s1, string s2) 
  if( len(s1) != len(s2))
    return false
  if( substring(s2,concat(s1,s1))
    return true
  return false
end

En Java:

boolean isRotation(String s1,String s2) {
    return (s1.length() == s2.length()) && ((s1+s1).indexOf(s2) != -1);
}
688
codaddict

Une meilleure réponse serait sûrement: "Eh bien, je demanderais à la communauté du stackoverflow et aurais probablement au moins 4 très bonnes réponses dans les 5 minutes". Les cerveaux sont bons et tous, mais je donnerais plus de valeur à quelqu'un qui sait comment travailler avec les autres pour trouver une solution.

101
Chris Knight

Un autre exemple python (basé sur LA réponse):

def isrotation(s1,s2):
     return len(s1)==len(s2) and s1 in 2*s2
49

Comme d'autres ont soumis la solution quadratique de complexité temporelle dans le pire des cas, je voudrais en ajouter un linéaire (basé sur le algorithme KMP ):

bool is_rotation(const string& str1, const string& str2)
{
  if(str1.size()!=str2.size())
    return false;

  vector<size_t> prefixes(str1.size(), 0);
  for(size_t i=1, j=0; i<str1.size(); i++) {
    while(j>0 && str1[i]!=str1[j])
      j=prefixes[j-1];
    if(str1[i]==str1[j]) j++;
    prefixes[i]=j;
  }

  size_t i=0, j=0;
  for(; i<str2.size(); i++) {
    while(j>0 && str2[i]!=str1[j])
      j=prefixes[j-1];
    if(str2[i]==str1[j]) j++;
  }
  for(i=0; i<str2.size(); i++) {
    if(j>=str1.size()) return true;
    while(j>0 && str2[i]!=str1[j])
      j=prefixes[j-1];
    if(str2[i]==str1[j]) j++;
  }

  return false;
}

exemple de travail

32
jpalecek

EDIT: La réponse acceptée est clairement plus élégante et efficace que cela, si vous la repérez. J'ai laissé cette réponse comme ce que je ferais si je n'avais pas pensé à doubler la chaîne d'origine.


Je voudrais juste le forcer brutalement. Vérifiez d'abord la longueur, puis essayez chaque décalage de rotation possible. Si aucun d'entre eux ne fonctionne, renvoyez false - si l'un d'entre eux réussit, renvoyez true immédiatement.

Il n'y a aucun besoin particulier de concaténer - utilisez simplement des pointeurs (C) ou des index (Java) et parcourez les deux, un dans chaque chaîne - en commençant au début d'une chaîne et le décalage de rotation candidat en cours dans la deuxième chaîne, et le retour à la ligne si nécessaire . Vérifiez l’égalité des caractères à chaque point de la chaîne. Si vous arrivez à la fin de la première chaîne, vous avez terminé.

Il serait probablement aussi facile de concaténer - bien que probablement moins efficace, du moins en Java.

25
Jon Skeet

En voici une qui utilise regex juste pour le plaisir:

boolean isRotation(String s1, String s2) {
   return (s1.length() == s2.length()) && (s1 + s2).matches("(.*)(.*)\\2\\1");
}

Vous pouvez le rendre un peu plus simple si vous pouvez utiliser un caractère de délimitation spécial qui garantit de ne pas figurer dans les deux chaînes.

boolean isRotation(String s1, String s2) {
   // neither string can contain "="
   return (s1 + "=" + s2).matches("(.*)(.*)=\\2\\1");
}

Vous pouvez également utiliser lookbehind avec une répétition finie à la place:

boolean isRotation(String s1, String s2) {
   return (s1 + s2).matches(
      String.format("(.*)(.*)(?<=^.{%d})\\2\\1", s1.length())
   );
}
17
polygenelubricants

Whoa, whoa ... pourquoi tout le monde est-il si heureux d'une réponse O(n^2)? Je suis convaincu que nous pouvons faire mieux ici. LA réponse ci-dessus inclut une opération O(n) dans une boucle O(n) (l'appel de sous-chaîne/indexOf). Même avec un algorithme de recherche plus efficace; disons Boyer-Moore ou KMP, le pire des cas est toujours O(n^2) avec des doublons.

Une réponse aléatoire O(n) est simple; prenez un hachage (comme une empreinte de Rabin) qui supporte une O(1) fenêtre glissante; chaîne de hachage 1, puis chaîne de hachage 2, puis déplacez la fenêtre du hachage 1 autour de la chaîne pour voir si les fonctions de hachage se rencontrent.

Si nous imaginons que le pire des cas ressemble à "l'analyse de deux brins d'ADN", la probabilité de collision augmente, ce qui dégénère probablement en quelque chose comme O(n^(1+e)) ou quelque chose (à deviner ici).

Enfin, il existe une solution déterministe O(nlogn) qui a une très grosse constante à l'extérieur. Fondamentalement, l’idée est de prendre une convolution des deux chaînes. La valeur maximale de la convolution sera la différence de rotation (si elles sont tournées); une vérification O(n) confirme. La bonne chose est que s’il ya deux valeurs maximales égales, elles constituent également des solutions valables. Vous pouvez faire la convolution avec deux FFT et un produit scalaire, et un iFFT, donc nlogn + nlogn + n + nlogn + n == O(nlogn).

Puisque vous ne pouvez pas utiliser de zéros et que vous ne pouvez pas garantir que les chaînes ont une longueur de 2 ^ n, les FFT ne seront pas les plus rapides. ce seront les plus lents, toujours O(nlogn), mais une constante bien plus grosse que l'algorithme CT.

Cela étant dit, je suis absolument convaincu à 100% qu'il existe une solution déterministe O(n) ici, mais maudite si je peux la trouver.

10
user295691

Poing, assurez-vous que les 2 cordes ont la même longueur. Ensuite, en C, vous pouvez le faire avec une simple itération de pointeur.


int is_rotation(char* s1, char* s2)
{
  char *tmp1;
  char *tmp2;
  char *ref2;

  assert(s1 && s2);
  if ((s1 == s2) || (strcmp(s1, s2) == 0))
    return (1);
  if (strlen(s1) != strlen(s2))
    return (0);

  while (*s2)
    {
      tmp1 = s1;
      if ((ref2 = strchr(s2, *s1)) == NULL)
        return (0);
      tmp2 = ref2;
      while (*tmp1 && (*tmp1 == *tmp2))
        {
          ++tmp1;
          ++tmp2;
          if (*tmp2 == '\0')
            tmp2 = s2;
        }
      if (*tmp1 == '\0')
        return (1);
      else
        ++s2;
    }
  return (0);
}
8
Opera

Voici un O(n) et un algorithme en place. Il utilise l'opérateur < pour les éléments des chaînes. Ce n'est pas à moi bien sûr. Je l'ai pris de ici (le site est en polonais. Je suis tombé dessus une fois dans le passé et je ne pouvais pas trouver quelque chose comme ça maintenant en anglais, donc je montre ce que j'ai :)).

bool equiv_cyc(const string &u, const string &v)
{
    int n = u.length(), i = -1, j = -1, k;
    if (n != v.length()) return false;

    while( i<n-1 && j<n-1 )
    {
        k = 1;
        while(k<=n && u[(i+k)%n]==v[(j+k)%n]) k++;
        if (k>n) return true;
        if (u[(i+k)%n] > v[(j+k)%n]) i += k; else j += k;
    }
    return false;
}
8
Maciej Hehl

Je suppose que c'est mieux de le faire dans Java:

boolean isRotation(String s1,String s2) {
    return (s1.length() == s2.length()) && (s1+s1).contains(s2);
}

En Perl je ferais:

sub isRotation {
 my($string1,$string2) = @_;
 return length($string1) == length($string2) && ($string1.$string1)=~/$string2/;
}

ou même mieux en utilisant la fonction index au lieu de l'expression régulière:

sub isRotation {
 my($string1,$string2) = @_;
 return length($string1) == length($string2) && index($string2,$string1.$string1) != -1;
}
7
Zacky112

Prenez chaque caractère comme une amplitude et effectuez une transformée de Fourier discrète sur eux. S'ils ne diffèrent que par la rotation, les spectres de fréquence seront identiques à l'erreur d'arrondi. Bien sûr, cela est inefficace sauf si la longueur est une puissance de 2, donc vous pouvez faire une FFT :-)

6
phkahler

Pas sûr que ce soit la méthode la plus efficace, mais cela pourrait être relativement intéressant : le transformation de Burrows-Wheeler . Selon l'article WP, toutes les rotations de l'entrée donnent la même sortie. Pour des applications telles que la compression, cela n’est pas souhaitable et la rotation initiale est indiquée (par exemple, par un index; voir l’article). Mais pour une simple comparaison indépendante de la rotation, cela semble idéal. Bien sûr, ce n'est pas nécessairement idéalement efficace!

6
Edmund

Personne n'a encore proposé d'approche modulo, alors en voici une:

static void Main(string[] args)
{
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "ztackoverflow"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "ackoverflowst"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "overflowstack"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "stackoverflwo"));
    Console.WriteLine("Rotation : {0}",
        IsRotation("stackoverflow", "tackoverflwos"));
    Console.ReadLine();
}

public static bool IsRotation(string a, string b)
{
    Console.WriteLine("\nA: {0} B: {1}", a, b);

    if (b.Length != a.Length)
        return false;

    int ndx = a.IndexOf(b[0]);
    bool isRotation = true;
    Console.WriteLine("Ndx: {0}", ndx);
    if (ndx == -1) return false;
    for (int i = 0; i < b.Length; ++i)
    {
        int rotatedNdx = (i + ndx) % b.Length;
        char rotatedA = a[rotatedNdx];

        Console.WriteLine( "B: {0} A[{1}]: {2}", b[i], rotatedNdx, rotatedA );

        if (b[i] != rotatedA)
        {
            isRotation = false;
            // break; uncomment this when you remove the Console.WriteLine
        }
    }
    return isRotation;
}

Sortie:

A: stackoverflow B: ztackoverflow
Ndx: -1
Rotation : False

A: stackoverflow B: ackoverflowst
Ndx: 2
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
Rotation : True

A: stackoverflow B: overflowstack
Ndx: 5
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
Rotation : True

A: stackoverflow B: stackoverflwo
Ndx: 0
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
B: o A[12]: w
Rotation : False

A: stackoverflow B: tackoverflwos
Ndx: 1
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
B: o A[12]: w
B: s A[0]: s
Rotation : False

[EDIT: 2010-04-12]

piotr remarqué la faille dans mon code ci-dessus. Il se trompe lorsque le premier caractère de la chaîne apparaît deux fois ou plus. Par exemple, stackoverflow testé sur owstackoverflow a pour résultat false, alors que cela devrait être vrai.

Merci piotr pour avoir repéré l'erreur.

Maintenant, voici le code corrigé:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace TestRotate
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ztackoverflow"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ackoverflowst"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "overflowstack"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "stackoverflwo"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "tackoverflwos"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "owstackoverfl"));

            Console.ReadLine();
        }

        public static bool IsRotation(string a, string b)
        {
            Console.WriteLine("\nA: {0} B: {1}", a, b);

            if (b.Length != a.Length)
                return false;

            if (a.IndexOf(b[0]) == -1 )
                return false;

            foreach (int ndx in IndexList(a, b[0]))
            {
                bool isRotation = true;

                Console.WriteLine("Ndx: {0}", ndx);

                for (int i = 0; i < b.Length; ++i)
                {
                    int rotatedNdx = (i + ndx) % b.Length;
                    char rotatedA = a[rotatedNdx];

                    Console.WriteLine("B: {0} A[{1}]: {2}", b[i], rotatedNdx, rotatedA);

                    if (b[i] != rotatedA)
                    {
                        isRotation = false;
                        break;
                    }
                }
                if (isRotation)
                    return true;
            }
            return false;
        }

        public static IEnumerable<int> IndexList(string src, char c)
        {
            for (int i = 0; i < src.Length; ++i)
                if (src[i] == c)
                    yield return i;
        }

    }//class Program
}//namespace TestRotate

Voici la sortie:

A: stackoverflow B: ztackoverflow
Rotation : False

A: stackoverflow B: ackoverflowst
Ndx: 2
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
Rotation : True

A: stackoverflow B: overflowstack
Ndx: 5
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
Rotation : True

A: stackoverflow B: stackoverflwo
Ndx: 0
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
Rotation : False

A: stackoverflow B: tackoverflwos
Ndx: 1
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
B: w A[11]: o
Rotation : False

A: stackoverflow B: owstackoverfl
Ndx: 5
B: o A[5]: o
B: w A[6]: v
Ndx: 11
B: o A[11]: o
B: w A[12]: w
B: s A[0]: s
B: t A[1]: t
B: a A[2]: a
B: c A[3]: c
B: k A[4]: k
B: o A[5]: o
B: v A[6]: v
B: e A[7]: e
B: r A[8]: r
B: f A[9]: f
B: l A[10]: l
Rotation : True

Voici l'approche lambda:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IsRotation
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ztackoverflow"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "ackoverflowst"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "overflowstack"));
            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "stackoverflwo"));

            Console.WriteLine("Rotation : {0}",
                IsRotation("stackoverflow", "owstackoverfl"));

            string strToTestFrom = "stackoverflow";
            foreach(string s in StringRotations(strToTestFrom))
            {
                Console.WriteLine("is {0} rotation of {1} ? {2}",
                    s, strToTestFrom,
                    IsRotation(strToTestFrom, s) );
            }
            Console.ReadLine();
        }

        public static IEnumerable<string> StringRotations(string src)
        {
            for (int i = 0; i < src.Length; ++i)
            {
                var sb = new StringBuilder();
                for (int x = 0; x < src.Length; ++x)
                    sb.Append(src[(i + x) % src.Length]);

                yield return sb.ToString();
            }
        }

        public static bool IsRotation(string a, string b)
        {
            if (b.Length != a.Length || a.IndexOf(b[0]) < 0 ) return false;
            foreach(int ndx in IndexList(a, b[0]))
            {
                int i = ndx;
                if (b.ToCharArray().All(x => x == a[i++ % a.Length]))
                    return true;
            }
            return false;
        }

        public static IEnumerable<int> IndexList(string src, char c)
        {
            for (int i = 0; i < src.Length; ++i)
                if (src[i] == c)
                    yield return i;
        }

    }//class Program

}//namespace IsRotation

Voici la sortie de l'approche lambda:

Rotation : False
Rotation : True
Rotation : True
Rotation : False
Rotation : True
is stackoverflow rotation of stackoverflow ? True
is tackoverflows rotation of stackoverflow ? True
is ackoverflowst rotation of stackoverflow ? True
is ckoverflowsta rotation of stackoverflow ? True
is koverflowstac rotation of stackoverflow ? True
is overflowstack rotation of stackoverflow ? True
is verflowstacko rotation of stackoverflow ? True
is erflowstackov rotation of stackoverflow ? True
is rflowstackove rotation of stackoverflow ? True
is flowstackover rotation of stackoverflow ? True
is lowstackoverf rotation of stackoverflow ? True
is owstackoverfl rotation of stackoverflow ? True
is wstackoverflo rotation of stackoverflow ? True
5
Michael Buen

Comme personne n'a donné de solution C++. voici le:

bool isRotation(string s1,string s2) {

  string temp = s1;
  temp += s1;
  return (s1.length() == s2.length()) && (temp.find(s2) != string::npos);
}
3
user324138

Une réponse pure Java (vérifications sans null)

private boolean isRotation(String s1,String s2){
    if(s1.length() != s2.length()) return false;
    for(int i=0; i < s1.length()-1; i++){
        s1 = new StringBuilder(s1.substring(1)).append(s1.charAt(0)).toString();
        //--or-- s1 = s1.substring(1) + s1.charAt(0)
        if(s1.equals(s2)) return true;
    }
    return false;
}
2
ring bearer

C #:

s1 == null && s2 == null || s1.Length == s2.Length && (s1 + s1).Contains(s2)
2
Anthony Faull

Le tour de pointeur simple utilisé par Opera fonctionne, mais il est extrêmement inefficace dans le pire des cas. Imaginez simplement une chaîne avec de nombreux cycles de caractères répétés, par exemple:

S1 = HELLOHELLOHELLO1HELLOHELLOHELLO2

S2 = HELLOHELLOHELLO2HELLOHELLOHELLO1

La "boucle jusqu'à ce qu'il y ait une discordance, puis incrémente d'une unité et essaie à nouveau" est une approche horrible, de calcul.

Pour prouver que vous pouvez utiliser la méthode de concaténation en clair C sans trop d'effort, voici ma solution:

  int isRotation(const char* s1, const char* s2) {
        assert(s1 && s2);

        size_t s1Len = strlen(s1);

        if (s1Len != strlen(s2)) return 0;

        char s1SelfConcat[ 2 * s1Len + 1 ];

        sprintf(s1SelfConcat, "%s%s", s1, s1);   

        return (strstr(s1SelfConcat, s2) ? 1 : 0);
}

Ceci est linéaire dans le temps d'exécution, au détriment de O(n) utilisation de la mémoire en temps système.

(Notez que l'implémentation de strstr () est spécifique à la plate-forme, mais si elle est particulièrement mortelle, elle peut toujours être remplacée par une alternative plus rapide telle que l'algorithme de Boyer-Moore.)

2
RarrRarrRarr

Et maintenant pour quelque chose de complètement différent.

Si vous voulez une réponse très rapide dans un contexte contraint lorsque les chaînes sont pas rotation les unes des autres

  • calculer une somme de contrôle basée sur les caractères (comme xorer tous les caractères) sur les deux chaînes. Si les signatures diffèrent, les chaînes ne sont pas des rotations les unes des autres.

D'accord, cela peut échouer, mais c'est très rapide à dire si les chaînes ne correspondent pas et si elles correspondent, vous pouvez toujours utiliser un autre algorithme comme la concaténation de chaînes à vérifier.

2
kriss

J'aime LA réponse qui vérifie si s2 est une sous-chaîne de s1 concaténée avec s1.

Je voulais ajouter une optimisation qui ne perd pas de son élégance.

Au lieu de concaténer les chaînes, vous pouvez utiliser une vue de jointure (je ne sais pas pour un autre langage, mais pour C++ Boost.Range fournir ce type de vues).

Comme la vérification si une chaîne est une sous-chaîne d'une autre a une complexité moyenne linéaire (la complexité du cas le plus défavorable est quadratique), cette optimisation devrait améliorer la vitesse d'un facteur 2 en moyenne.

2

Inverser l'une des chaînes. Prenez la FFT des deux (en les traitant comme de simples séquences d’entiers). Multipliez les résultats ensemble point par point. Transformer en arrière en utilisant FFT inverse. Le résultat aura un seul pic si les chaînes sont des rotations les unes des autres - la position du pic indiquera de combien elles sont pivotées les unes par rapport aux autres.

1
brewbuck

Il est très facile d'écrire en PHP en utilisant les fonctions strlen et strpos:

function isRotation($string1, $string2) {
    return strlen($string1) == strlen($string2) && (($string1.$string1).strpos($string2) != -1);
}

Je ne sais pas ce que strpos utilise en interne, mais s'il utilise KMP , ce sera linéaire dans le temps.

1
user325894

Une autre solution Ruby basée sur le answer :

def rotation?(a, b); a.size == b.size and (b*2)[a]; end
1
Anurag

Pourquoi pas quelque chose comme ça?


//is q a rotation of p?
bool isRotation(string p, string q) {
    string table = q + q;    
    return table.IndexOf(p) != -1;
}

Bien sûr, vous pouvez écrire votre propre fonction IndexOf (); Je ne sais pas si .NET utilise une méthode naïve ou une méthode plus rapide.

Naïve:


int IndexOf(string s) {
    for (int i = 0; i < this.Length - s.Length; i++)
        if (this.Substring(i, s.Length) == s) return i;
    return -1;
}

Plus rapide:


int IndexOf(string s) {
    int count = 0;
    for (int i = 0; i < this.Length; i++) {
        if (this[i] == s[count])
            count++;
        else
            count = 0;
        if (count == s.Length)
            return i - s.Length;
    }
    return -1;
}

Edit: J'ai peut-être des problèmes particuliers; ne pas envie de vérifier. ;)

0
hehewaffles

Je ferais ceci dans Perl:

sub isRotation { 
     return length $_[0] == length $_[1] and index($_[1],$_[0],$_[0]) != -1; 
}
0
gameover

Joignez string1 avec string2 et utilisez algorithme KMP pour vérifier si string2 est présent dans la nouvelle chaîne. Parce que la complexité temporelle de KMP est inférieure à substr.

0
CrazyCoder
int rotation(char *s1,char *s2)
{
    int i,j,k,p=0,n;
    n=strlen(s1);
    k=strlen(s2);
    if (n!=k)
        return 0;
    for (i=0;i<n;i++)
    {
        if (s1[0]==s2[i])
        {
            for (j=i,k=0;k<n;k++,j++)
            {
                if (s1[k]==s2[j])
                    p++;
                if (j==n-1)
                    j=0;
            }
        }
    }
    if (n==p+1)
      return 1;
    else
      return 0;
}
0
mannrecaged