这段代码来自w3resource,如何理解charPermu在主代码中的作用,特别是指针参数

kqlmhetl  于 2023-03-01  发布在  其他
关注(0)|答案(1)|浏览(87)

目前,我正在做w3 resource中关于指针的练习。请帮我解释一下charPermu的参数,以及为什么在主代码中给出(str,0,n-1)?

#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;
    
}
tzdcorbm

tzdcorbm1#

哇,对于教程来说,这是 * 可怕的 * 变量命名。让我们给予一些更有用的名称:

#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;
    
}

这些变量名可能并不完美,但至少它们读起来像英语。始终记住变量名是为了帮助人类读者,而不是计算机。
现在,我们可以查看参数,并看到:

  • fullString始终是指向内存中字符串开头的指针;我们需要这样做,因为即使我们只改变了字符串的一部分,我们也要打印整个字符串
  • startingOffset在我们第一次调用函数时为零--没有偏移量,所以是字符串中的第一个字符--并且在每次递归调用自身时增加1
  • endingOffset始终保持设置为字符串中的最后一个字符-对于4个字符的字符串,偏移量为3将获得最后一个字符;它可以让我们检测到字符串的末尾

其思想是,函数的每次执行都交换 * 一个 * 字符,然后调用自身来生成 * 该点之后字符串的其余部分 * 的所有排列。
因此,当startingOffset为0时,for循环将字符串中的每个字符依次放在首位,然后“固定”第一个字符以进行递归调用;然后,它将在每个可能的字符上循环 second place(offset 1),并将其固定,等等。一旦所有字符都“固定”,开始和结束偏移量将相同,我们打印结果并返回以继续进行不同的组合。

相关问题