字符串组合求法

题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。

上面我们详细讨论了如何用递归的思路求字符串的排列。同样,本题也可以用递归的思路来求字符串的组合。

方法一:
假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;第二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。下面是这种思路的参考代码:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
#include<assert.h>

void Combination(char *string ,int number,vector<char> &result);

void Combination(char *string)
{
    assert(string != NULL);
    vector<char> result;
    int i , length = strlen(string);
    for(i = 1 ; i <= length ; ++i)
        Combination(string , i ,result);
}

void Combination(char *string ,int number , vector<char> &result)
{
    assert(string != NULL);
    if(number == 0)
    {
        static int num = 1;
        printf("第%d个组合	",num++);

        vector<char>::iterator iter = result.begin();
        for( ; iter != result.end() ; ++iter)
            printf("%c",*iter);
        printf("
");
        return ;
    }
    if(*string == '')
        return ;
    result.push_back(*string);
    Combination(string + 1 , number - 1 , result);
    result.pop_back();
    Combination(string + 1 , number , result);
}

int main(void)
{
    char str[] = "abc";
    Combination(str);
    return 0;
}

由于组合可以是1个字符的组合,2个字符的字符……一直到n个字符的组合,因此在函数void Combination(char* string),我们需要一个for循环。另外,我们用一个vector来存放选择放进组合里的字符。
方法二:用位运算来实现求组合

#include<iostream>
using namespace std;

int a[] = {1,3,5,4,6};
char str[] = "abcde";

void print_subset(int n , int s)
{
    printf("{");
    for(int i = 0 ; i < n ; ++i)
    {
        if( s&(1<<i) )         // 判断s的二进制中哪些位为1,即代表取某一位
            printf("%c ",str[i]);   //或者a[i]
    }
    printf("}
");
}

void subset(int n)
{
    for(int i= 0 ; i < (1<<n) ; ++i)
    {
        print_subset(n,i);
    }
}



int main(void)
{
    subset(5);
    return 0;
}

题目:输入两个整数n和m,从数列1,2,3...n中随意取几个数,使其和等于m,要求列出所有的组合。

#include <iostream>
#include <list>
using namespace std;
list<int> list1;
void find_factor(int sum,int n)
{
    //递归出口
    if(n<=0||sum<=0)
        return;
    //输出找到的数
    if(sum==n)
    {
        list1.reverse();
        for(list<int>::iterator iter=list1.begin();iter!=list1.end();iter++)
            cout<<*iter<<"+";
        cout<<n<<endl;
        list1.reverse();
    }
    list1.push_front(n);
    find_factor(sum-n,n-1);//n放在里面
    list1.pop_front();
    find_factor(sum,n-1);//n不放在里面
}

int main(void)
{
    int sum,n;
    cin>>sum>>n;
    cout<<"所有可能的序列,如下:"<<endl;
    find_factor(sum,n);
    return 0;
}
原文地址:https://www.cnblogs.com/xiaodi914/p/5804205.html