如何删除此代码的重复排列?

时间:2018-10-29 06:31:18

标签: c++ algorithm recursion permutation backtracking

我正在尝试生成字符串的排列。这段代码可以正常工作,但是当重复一个char时,将打印重复的排列。示例如下。

string s;
int num[50], used[50], cur[50];

void permute(int start, int len)
{
    if(start == len)
    {
        for(int i = 0; i < len; i++)
            printf("%c", s[num[i]]);
        printf("\n");
        return;

    }

    for(int i = 0; i < len; i++)
    {

        if(used[i] == 0)
        {
            used[i] = 1;
            num[start] = i;
            permute(start+1, len);
            used[i] = 0;
        }
    }
}

输入:

aab

输出:

aab
aba
aab
aba
baa
baa

1 个答案:

答案 0 :(得分:0)

在程序中,对于每个start位置,您都运行一个for循环,直到字符串的长度。如果字符串包含重复字符,则它将多次出现。这将导致重复排列。因此,您必须确保同一字符不会在特定的start位置出现多次。您可以使用附加数组isCharUsed来执行此操作,以跟踪以前是否使用过字符。我的解决方案如下:

string s;
int num[50], used[50], cur[50];

void permute(int start, int len)
{
    if(start == len)
    {
        for(int i = 0; i < len; i++)
            printf("%c", s[num[i]]);
        printf("\n");
        return;

    }

    // to keep track whether this character used before or not
    bool isCharUsed[27] = {0};

    for(int i = 0; i < len; i++)
    {

        if(used[i] == 0 && isCharUsed[s[i]-'a'] == false)
        {
            // set true for this character, so that it does not appear again
            isCharUsed[s[i]-'a'] = true;

            used[i] = 1;
            num[start] = i;
            permute(start+1, len);
            used[i] = 0;
        }
    }
}

输入:

aab

输出:

aab
aba
baa