Apr 27, 2013

生成字符串的全排列

递归的方法比较简单,略过。

非递归方法首先需要将字符串排序,然后循环查找下一个比当前字排列大的字符串。举例来说,当前字符串是1 5 7 6 4 3 2,我们知道下一个应该是1 6 2 3 4 5 7,怎么找到的呢?
从右边往左扫描,找到第一个比左边字符大的字符,本例中我们找到了7,然后将7左边的字符(5)与与右边的字符(6 4 3 2)比较,找到(6 4 3 2)中比5大的字符,本例中是6,将5与6交换,然后反转7右边的字符(将5 4 3 2反转成2 3 4 5)。

思路清楚之后,程序就很简单了,并且能处理重复字符的情况(如果用递归的方法,需要检测重复字符进行处理)。

void permutation(char *s, int n)
{
    std::sort(s, s + n);
    printf("%s\n", s);
    int i, j;
    while (1) {
        for (i = n-1; i>=1 && s[i]<=s[i-1]; --i)
            ;
        if (i == 0)
            break;
        for (j = n-1; j>i && s[j]<=s[i-1]; --j)
            ;
        std::swap(s[i-1], s[j]);
        for (j = n-1; i < j; ++i, --j)
            std::swap(s[i], s[j]);
        printf("%s\n", s);
    }
}

No comments:

Post a Comment