Search code examples
cstringpointerspositionpermutation

This excercise is from w3resource. How to figure out what charPermu's job in the main code especially the pointer parameter, please


Currently, I am working on the exercises from w3resource about pointers. Help me explaining the parameters of charPermu and why it is given (str, 0, n -1) in the main code please?

#include <stdio.h>
#include <string.h>
#define MAX 4

void changePos(char *ch1, char *ch2){
    char tmp;
    tmp = *ch1;
    *ch1 = *ch2;
    *ch2 = tmp;
}

void charPermu(char *cht, int stno, int endno){
    int i;
    if(stno == endno){
        printf("%s ", cht);
    } else{
        for(i = stno; i<= endno; i++){
            changePos((cht+stno), (cht+i));
            charPermu(cht, stno+1, endno);
            changePos((cht+stno), (cht+i));
        }
    }
}

int main(){
    char str[MAX];
    printf("\n\n Pointer : Generate permutations of a given string :\n"); 
    printf("--------------------------------------------------------\n"); 
    printf("Enter a string to permutate: ");
    scanf("%[^\n]", str);
    int n = strlen(str);
    printf("The permutations of the string are: ");
    charPermu(str, 0, n - 1);
    printf("\n\n");
    return 0;
    
}

Solution

  • Wow, for a tutorial, that is terrible variable naming. Let's give things more useful names:

    #include <stdio.h>
    #include <string.h>
    #define MAX_STRING_LENGTH 4
    
    void swapCharacters(char *ch1, char *ch2){
        char tmp;
        tmp = *ch1;
        *ch1 = *ch2;
        *ch2 = tmp;
    }
    
    void printPermutations(char *fullString, int startingOffset, int endingOffset){
        int nextOffset;
        if(startingOffset == endingOffset){
            printf("%s ", fullString);
        } else{
            for(nextOffset = startingOffset; nextOffset<= endingOffset; nextOffset++){
                swapCharacters((fullString+startingOffset), (fullString+nextOffset));
                printPermutations(fullString, startingOffset+1, endingOffset);
                swapCharacters((fullString+startingOffset), (fullString+nextOffset));
            }
        }
    }
    
    int main(){
        char input[MAX_STRING_LENGTH];
        printf("\n\n Pointer : Generate permutations of a given string :\n"); 
        printf("--------------------------------------------------------\n"); 
        printf("Enter a string to permutate: ");
        scanf("%[^\n]", input);
        int stringLength = strlen(input);
        printf("The permutations of the string are: ");
        printPermutations(input, 0, stringLength - 1);
        printf("\n\n");
        return 0;
        
    }
    

    These names probably aren't perfect, but at least they read as English. Always remember that variable names are for the aid of the human reader, not the computer.

    Now we can look at the parameters, and see that:

    • fullString is always the pointer to the beginning of the string in memory; we need this, because even if we're only changing part of the string, we want to print the full thing
    • startingOffset is zero the first time we call the function - no offset, so the first character in the string - and increased by one each time it recursively calls itself
    • endingOffset always stays set to the last character in the string - for a 4-character string, an offset of 3 gets you the last character; it lets us detect when we've got to the end of the string

    The idea is that each execution of the function swaps one character, and then calls itself to generate all the permutations of the rest of the string after that point.

    So when startingOffset is zero, the for loop is putting each character of the string in turn in first place, then "fixing" that first character for the recursive call; that will then loop over each possible character for second place (offset 1), and fix that, and so on. Once all characters are "fixed", starting and ending offsets will be the same, and we print the result and return to carry on with a different combination.