置换字符串不按预期工作

时间:2017-11-03 13:48:59

标签: c

我试图创建一个功能,该功能可以置换一个单词的所有可能组合,并且程序会创建置换字符串的副本,我无法弄清楚原因。

这是我的工作代码:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char arr[5000] = {0};
void swap (char *x, char *y);
void permute(char *ptr, size_t i, size_t n);

int main(void){
    char str[80] = "MICHI";
    size_t len = strlen(str);

    permute(str, 0, len );
    printf("%s\n", arr);
    printf("END\n");
}

void swap (char *x, char *y){
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

void permute(char *ptr, size_t i, size_t n){
    size_t j;
    if (i == n){
        strcat (arr, ptr);
        strcat (arr, "\n");
    }else{
        for (j = i; j <= n; j++)
        {

            swap( (ptr + i), (ptr + j) );
            permute(ptr, i+1, n);
            swap( (ptr + i), (ptr + j) );
        }
    }
}

这是输出:

ABC
AB
ACB
AC
A
A
BAC
BA
BCA
BC
B
B
CBA
CB
CAB
CA
C
C







END

预期产出应为:

ABC
AB
ACB
AC
A
BAC
BA
BCA
BC
B
CBA
CB
CAB
CA
c

该程序会创建大量重复项,并且还会创建大量新行。

注意到如果INPUT是例如MICHI,我会得到这样的重复:

IMCHI
IMCH
IMCIH
IMCI

2 个答案:

答案 0 :(得分:3)

您在排列中包含字符串终止符\0

line的内部状态是:

ABC\0
AB\0C
ACB\0
AC\0B
A\0CB
A\0BC
BAC\0
BA\0C
BCA\0
BC\0A
B\0AC
B\0CA
CBA\0
CB\0A
CAB\0
CA\0B
C\0AB
C\0BA
\0ABC
\0ACB
\0BAC
\0BCA
\0CAB
\0CBA

printf仅打印到结尾0

解决此问题的一种方法是将循环限制减少一个,并从排列中排除\0。然后,您必须添加第二个循环,该循环创建一个排除i个字符的子字符串,并为该子字符串调用permute

另一种方法是在分支超出\0时停止置换。

修改

这是第二个建议的实现,即如果排列与前一个排列相同,则通过抑制输出来“停止置换”。它甚至似乎产生了你在例子中指定的顺序:

void permute(char *ptr, size_t i, size_t n){
    size_t j;
    static char prev[80] = "";
    if (i == n){
        if (strcmp(prev, ptr)) {
            strcat (arr, ptr);
            strcat (arr, "\n");
            strcpy(prev, ptr);
        }
    }else{
        for (j = i; j <= n; j++)
        {

            swap( (ptr + i), (ptr + j) );
            permute(ptr, i+1, n);
            swap( (ptr + i), (ptr + j) );
        }
    }
}

答案 1 :(得分:2)

函数permute中的循环包含字符串的NUL字节。您只需将j <= n更改为j < n即可。 像这样:

void permute(char *ptr, size_t i, size_t n){
    size_t j;
    if (i == n){
        strcat (arr, ptr);
        strcat (arr, "\n");
    }else{
        for (j = i; j < n; j++)
        {

            swap( (ptr + i), (ptr + j) );
            permute(ptr, i+1, n);
            swap( (ptr + i), (ptr + j) );
        }
    }
}