A Recursive Permutation Function

Of course recursion is scary! At no other time in your programming career is your code more susceptible to stack overflows, which appear on the screen as ugly system errors when the code runs. I find that exciting.

Recursion is a solution to the permutation problem when the length of text characters isn’t fixed. Instead, the length is a variable; the string is n characters long. The permutations range from aaa...a through zzz...z. So the string’s length is what the recursive function must deal with, and that length is what determines when the function starts to unwind.

Inside the recursive function you need a loop to generate characters from a to z. The recursive nature of the function slides that loop’s position to each element in the array, from 0 through n.

Sounds weird? Yeah, it is.

Click here to view the full code for the recursive password-cracking program. The recursive function is named compare(), which is listed here:

int compare(int pos,int len,char *s1,char *s2)
{
    char c;

    if( pos == len)
    {
        if( strcmp(s1,s2)==0 )
        {
            printf("%s -> %s\n",s1,s2);
            return(TRUE);
        }
        else
            return(FALSE);
    }
    else
    {
        for( c='a'; c<='z' ; c++ )
        {
            s1[pos] = c;
            pos++;
            if( compare(pos,len,s1,s2) )
                return(TRUE);
            pos--;
        }
    }
    return(FALSE);
}

The function contains two parts. The first is at Line 30:

    if( pos == len)

pos is the position indicator, the key that eventually unwinds the recursion. It represents the character position in string s1. When its length is equal to the length of string s2, a comparison is made. The compare() function then returns to itself with a value of either TRUE or FALSE, depending on the results of the strcmp() function.

It may seem like pos is greater than len, which is confusing. Remember that pos references an array element. The last character in a 4-character string sits at element 3 in the array. When pos is equal to len, both strings are the same size and can be compared.

The second part is the condition when the two strings aren’t of equal length, which starts with the else statement at Line 40. In this chunk of code, the compare() function builds string s1.

The for loop at Line 42 marches from a to z. The character is put into element pos in char array s1. The position pos is incremented to the next element in the array. compare() is called recursively at Line 46 to process that next element.

As long as pos < len, the else portion of the compare() function continues to build string s1. Eventually, the string aaa...a is created, which is equal to the length of target string s2. At that point, pos == len and the strings are compared. If the strings match, TRUE is returned and the recursion unwinds. Otherwise, FALSE is returned. At that point, Line 48, the pos indicator is decremented, and the next letter in the loop is processed, aaa...b.

The for loop continues to change each character in the s1 array, just as the nested loops did in an earlier post. As long as the compare() function returns to itself with a FALSE value, the loop keeps permuting string s1. It spins through all permutations up until zzz...z and finally returns FALSE at Line 51 when the two strings cannot match.

This recursive technique isn’t any faster than a solution using nested for loops; the longer the string you type, the longer it takes Mr. Computer to crunch the results. A long string composed of a’s and b’s will process more quickly. If you type a long string with lots of z’s in it, expect to wait a while.

The only advantage of using recursion is that the same function works regardless of the length of the target string.

Leave a Reply