String Rotation
January 31, 2012
We have today another question from our never-ending supply of interview questions:
Write a function that takes two input strings and determines if one is a rotation of the other. For instance, “ProgrammingPraxis” and “PraxisProgramming” are rotations of each other, but “ProgrammingPrasix” is not a rotation of “ProgrammingPraxis” because the last three letters are out of order.
Your task is to write the requested function. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
In Haskell:
Besser so:
having an easy way to rotate strings in APL, rotating only those amounts that would make the first characters match seemed like a neat little optimization:
isRotation←{1∊⍺∘≡¨(¯1+{⍵/⍳⍴⍵} ⍵=⍬⍴⍺)∘.⌽⊂⍵}
but, the length match test, and the looking within a concatenated pair of the target is much neater, without the messy match and actual rotates.
isRotation2←{~(⍴⍺)≡⍴⍵:0 ⋄ 1∊⍺⍷⍵,⍵}
The written code in C:
#include
#include
#include
int is_rotate(char* str1, char* str2){
int newlen = (strlen(str1) == strlen(str2)) ? 2*strlen(str1) : 0;
if (!newlen)
return 0;
char* str_concat = (char*) malloc( newlen + 1);
strcpy(str_concat, str1);
strcat(str_concat, str1);
str_concat [newlen] = ”;
printf(“String1: %s\n”, str1);
printf(“String2: %s\n”, str2);
printf(“Concats: %s\n\n”, str_concat);
char* substr = strstr(str_concat, str2);
if (!substr)
return 0;
else
return 1;
}
int main() {
char string1[] = “Hi_Amir_How_Are_You_Amir_”;
char string2[] = “How_Are_You_Amir_Amir_Hi_”;
char string3[] = “How_Are_You_Amir_Hi_Amir_”;
printf(“===> Str1 & Str2 Are%s Equal.\n\n”, (is_rotate(string1, string2)) ? “” : ” \”NOT\””);
printf(“===> Str1 & Str3 Are%s Equal.\n\n”, (is_rotate(string1, string3)) ? “” : ” \”NOT\””);
return;
}
Okay, Mr. Programming Praxis – here’s my brute force approach, using PL/SQL. (I should have read your elegant solution first.)
Here is one solution in C which does not require memory allocation and string concatenation:
Apparently I had the same idea as Georg.
THis is how I did in C++, [look amateur]:
#include
#include
using namespace std;
bool isRotateString(string, string);
int main()
{
string s1,s2;
cout <> s1;
cout <> s2;
if ((isRotateString(s1,s2)) == true)
cout << "YES!!!";
else cout <= 0; –i)
{
c = s1[i];
if (s1[i] == toupper(c))
{
rString += s1.substr(i, m – i);
m -= (m – i);
}
}
cout << "Rotated string : " << rString << endl;
if (rString == s2)
return true;
else return false;
}
}
Geez. I had forgotten how painful it is to write in imperative languages, especially when one has to do everything manually!
Language is Ada (because C should be forbidden.)
I used a concatenation approach instead of modulo, for no special reason.
Common Lisp FTW \o/
What a cool trick the model answer is. Before seeing it, I thought the problem merely tedious.
Here is an expansive answer, just for fun. (Python 3 it is.)
In python, the obvious solution is:
An alternative:
import re
def is_rotation(s1, s2):
return any(s1.startswith(s2[i:]) and s1.endswith(s2[:i]) for i in (mo.start() for mo in re.finditer(s1[0], s2)))
Mike: In your first solution, you must also check that the two strings are the same length. Otherwise, you will erroneously report that the two strings are rotations if s1 is a substring of s2.
It appeared to me in the description that the rotation function is based on words in the string and not the string itself, so I wrote a solution that splits the string into words and compares the reverse of the second to the first: http://codepad.org/G1ws5Bu3
It is somewhat generic; allowing the user to pass in a function that interprets whether a given character in the string is a delimiter and whether to include said delimiter as part of the word.
For trivial functions like this I tend to write doctests since they’re pretty quick for getting you started. Documentation also flows a little more naturally with them as you explore the various cases.
hot perl action using OPs wizardry:
simply-C-ty :P
isRotation(String str1,String str2)
//Check lengths
if(length(str1)!=length(str2))
return false
end if
else
//concat the string with itself and check if the concatenated string is a substring of str1
String str3=str2+str2
return str3.contains(str1)
end else
//method in java
public boolean isRotation(String str1,String str2)
{
if(str1.length()!=str2.length())
return false;
else
{
String str3=str2+str2;
return str3.contains(str1);
}
}
I liked Nick’s solution!
Here I’ve tried it to solve using regex in Java.
My first submission!
Using substrings in Java:
public static boolean Stringrot(String s1, String s2){
int cnt = 0;
if(s1.length() !=s2.length()){
return false;
}
while(cnt<s1.length() && s2.contains(s1.substring(0,++cnt))){}
if(s2.contains(s1.substring(cnt-1))){
return true;
}
else{
return false;
}
}
Let the given two strings are string1 and string2. We have to check whether string2 is a rotation of string1. The algorithm works as :
Check the length of the two strings. If they are not same, return false.
Otherwise, concatenate string1 with itself and check whether string2 is a substring of it.
For explanation and code http://www.algoqueue.com/algoqueue/default/view/7208960/check-whether-one-string-is-a-rotation-of-another
@Lal
I have tried both methods. The second method does not work for the word combination “affenzoo” vs. “zooaffen”. (i.e. monkey zoo).
Can you clarify?
Thank you,
http://pastebin.com/60CusEQc