zoukankan      html  css  js  c++  java
  • 字符串组合求法

    题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入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;
    }
  • 相关阅读:
    「题解」:07.16NOIP模拟T1:礼物
    「题解」:07.16NOIP模拟T2:通讯
    「题解」:图论专题总结
    07.07NOIP模拟赛
    [复习]平衡树splay
    「题解」:[组合数学][DP]:地精部落
    「题解」:[组合数学]:Perm 排列计数
    「题解」:[组合数学]:排队
    dp 杂题
    插头 dp 总结
  • 原文地址:https://www.cnblogs.com/xiaodi914/p/5804205.html
Copyright © 2011-2022 走看看