# Cyclic rotation in PHP?

I want to make a function that can take 2 strings as input, and then output me whether the strings are cyclic or not? For example, CAR, ARC, RCA are the cyclic rotations of themselves.

hi mohansinth,

This should do the trick:

<?php
echo checkCyclical('ARC','CAR') . '<br />';
echo checkCyclical('ARB','CAR') . '<br />';
/*Outputs
* 1
* 0
*/
function checkCyclical(\$root_string, \$comparitive_string){
\$arr1 = array();
\$arr1 = str_split(\$root_string);
\$arr2 = array();
\$arr2 = str_split(\$comparitive_string);
sort(\$arr1);
sort(\$arr2);
\$sorted_root_string = '';
\$sorted_comparitive_string = '';
\$sorted_root_string = implode('', \$arr1);
\$sorted_comparitive_string = implode('', \$arr2);
if(\$sorted_root_string == \$sorted_comparitive_string){
return 1;
} else {
return 0;
}
}
?>

@SS: That’s not cyclic, that just seems to check whether or not the strings contain the same characters. A single cyclic rotation left involves moving the first item to the end, then of course moving everything up one. For example, “car” would become “arc”, then “rca” then “car” again. However, “rac”, “cra” and “acr” are not cyclic rotations of “car”, though they do contain the same characters. Also unsure on the setting of things to blank before setting them as values, have you been using a typed programming language recently?

As far as I can see, the only way to check for a cyclical relationship is to actually cycle through the cyclic permutations of the string until you come across the matching string. However, you can do some checks first to filter out very different strings, like (“car”, “motorcycle”), and (“car”, “ant”). You can do this by checking sizes and the sum of the integer values of the ascii values of each character in each. There are possibilities of strings that will get past this initial checking (e.g. (“try”, “ssy”) have the same totals and size), but with longer strings (where a loop through every possibility could cause a performance hit) such cases (same size AND same total) are less and less likely.

function areCyclic(\$Initial, \$Compare){
\$Initial = (string)\$Initial;
\$Compare = (string)\$Compare;

if(\$Initial == \$Compare){
return true;
}
if((\$Length = strlen(\$Initial)) != strlen(\$Compare)){
return false;
}

\$TotalInitial = 0;
\$TotalCompare = 0;
for(\$i = 0; \$i < \$Length; \$i++){
\$TotalInitial += ord(\$Initial[\$i]);
\$TotalCompare += ord(\$Compare[\$i]);
}
if(\$TotalInitial != \$TotalCompare){
return false;
}
/*
* Chances are fairly good that the string contains the same characters now.
* Strings that differ significantly will have been filtered out by now to save
* on the processing. Now for the more fun part:
*/
for(\$i = 0; \$i < \$Length; \$i++){
\$Initial = substr(\$Initial, 1) . \$Initial[0];
if(\$Initial == \$Compare){
return true;
}
}
return false;
}
var_dump(areCyclic('car', 'rca')); // true
var_dump(areCyclic('car', 'cra')); // false
var_dump(areCyclic(12345, 23451)); // true
var_dump(areCyclic(12345, 54321)); // false
var_dump(areCyclic('This is a cyclic string', 'cyclic stringThis is a ')); // true
var_dump(areCyclic('This is a cyclic string', 'This is a string cyclic')); // false

Hi Jake,

Ok I understand what is meant by cyclical then, thanks (also for the example).

I have been using a typed programming language quite a lot lately so that is probably getting into that habit. It is more verbose in PHP but it will do no harm (other than more code) (;

Regards,
Steve

Here’s another option that should work. (Mushed onto one line to make you think a bit.) (:

function areCyclic(\$a, \$b) {
return strlen(\$a) === strlen(\$b) && strpos(\$a . \$a, (string) \$b) !== FALSE;
}

Very elegant solution!

Agreed, that is some beautiful logic right there.

Amazing and one line of code making the compiler work less Love the part of doubling the first string to so that all cyclical possibilities are shown.

Hi Everyone, thanks for your help.
Thanks to Salathe for giving a great 1 line solution for this.
Cheers!