排列组合

排列 组合

排列

字符串的全排列
这种是给你一个序列,让你找出他的全排列,每个位置不重复。(交换)
例如 abc的全排列有 abc, acb, bac, bca, cab, cba

还有一种是每个位置可以重复。(所有可能)
例如 abc的全排列   aaa, aab, aac, aba, abb,abc,....
类似于 输出求n位的每个数 0 ~ 9999....9(n位), 前面的例题。

!!!!对于这种问题,我们把 字符串看成2部分
第一部分  是字符串的第一个字符
第二部分  是字符串的后面的所有字符。

对于交换,先求出第一部分所有可能,再将第一部分的字符和第二部分的所有字符交换。
关于所有可能,先求出第一部分所有可能,和第二部分所有可能。
对于第二部分再递归调用。再看成2部分。

递归函数

/// index 用来监测是否递归到最后了,到最后则输出。
paiLie(char * a, char *index)
{
    if('\0' == *index )
        cout<< a <<endl;    ///到达末尾,可以输出了
    else
    {
        /// (1)交换的话
        char tmp, *p;
        for(p = index; *p != '\0'; ++p)
        {
            tmp = *p;
            *p = *index;
            *index = tmp;


            paiLie(a, index + 1);


            tmp = *p;
            *p = *index;
            *index = tmp;
        }


        ///(2)所有可能
        int i;
        for(i = 0; i < 10; ++i)
        {
            *p = '0' + i;
            paiLie(a, index+1);
        }
        ///(3) 上面是每一位都是0~9的数字,还可以指定每一位的取值范围
        ///     这样函数的参数就有需要添加一个base[]
        ///     paiLie(char * a, char *index, char * base, int baseNum)
        int i;
        for(i = 0; i < baseNum; ++i)
        {
            *p = base[i];
            paiLie(a, index + 1, base);
        }
    }
}


/// index 用来监测是否递归到最后了,到最后则输出。
调用该递归函数的话。

main()
{
    char a[N+1];
    a[N] = '\0';
    paiLie(a, a);
}


组合

(2)字符的所有组合

例如 abc 的所有组合--- a ,b, c, ab, ac, bc, abc = (2 ^3 -1) 种


n个字符,有 1 , 2, 3, ... n种组合。
对于每一种组合来说,组合数为m ,  1<= m <= n;
(1)包括第一个字符, + 不包括第一个字符的m-1个字符的组合
(2)不包括第一个字符 + 不包括第一个字符的m个字符的组合


<span style="font-size:18px;">allZuhe(char * base)
{
    int length = strlen(base);
    char *result = new char[length + 1];
    for(i = 1; i <= length; ++i)
    {
        allZuhe_recurse(base, 0, result, 0, i);
    }
    delete[] result;
}


allZuhe_recurse(char *base, int baseIndex,
                char *result, int resultIndex, int zuheNum)
{
    if(0 == zuheNum)
    {
        result[resultIndex] = '\0';
        cout<<result<<endl;
    }
    else
    {
        if('\0' != base[baseIndex])
        {
            /// 包括第一个字符 + 不包括第一个字符的m-1个字符的组合。
            result[resultIndex] = base[baseIndex];
            allZuhe_recurse(base, baseIndex+1, result, resultIndex+1, zuheNum-1);


            /// 不包括第一个字符 + 不包括第一个字符的m个字符的组合。
            allZuhe_recurse(base, baseIndex, result, resultIndex, zuheNum);
        }
    }
}</span>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值