子集生成——二进制方法与递归方法

来源:互联网 发布:2016淘宝如何打造爆款 编辑:程序博客网 时间:2024/05/24 15:42

二进制方法:

#include <iostream>#include <vector>using namespace std;int n ;vector<string > con;void get_sub(int input) {    cout << "{ ";    for (int i = 0; i < n; ++i)    {        if (input & (1 << i)) //检查二进制不同位的0-1情况。如果为1 就输出i;        {            cout << con[i] << " ";        }    }    printf("}\n");}int main(int argc, char const *argv[]){    string length;    while (1) {        cout << "请您输入元素的个数(不要超过100000000):(输入q退出)" << endl;        cin >>  length;        if (length[0] == 'q' && length.size() == 1) {            cout << "感谢您的使用!" << endl;            break;        }        int i = 0;        while ( '0' <= length[i] && length[i] <= '9')        {            i++;        }        if (i == (length.size() ))        {            n = atoi( length.c_str() );            if (n > 100000000)            {                cout << "对不起,您输入的数字太大。\n请您重新输入:" << endl;            } else if (n == 0)            {                cout << "对不起,您输入的数字为负数。\n请您重新输入:" << endl;            } else {                cout << "您输入集合的阶为: " << n << endl;                for (int i = 0; i < n; ++i)                {                    string temp;                    cin >> temp;                    con.push_back(temp);                }                printf("您输入的集合为:{ ");                for (int i = 0; i < n; ++i)                {                    cout << con[i] << " " << endl;                }                printf("}\n下面输出其子集:\n");                for (int i = 0; i < (1 << n); i++)//对于一个n个元素的集合 其子集有2^n-1个                {                    get_sub(i); //输入不同的二进制数。                    /*  例如:                    001                    010                    011                    100                    101                    110                    111                    注意 : 不含空集;                    */                }                printf("{ }\n");                printf("该集合总共有子集 %d 个\n", 1 << n);            }        } else {            cout << "请输入大于0的数字" << endl;        }        con.clear();    }    return 0;}

递归方法:

#include <iostream>#include <vector>#include <cstring>using namespace std;int n;vector<string> con;vector <int> indexcon;//indexcon代表下标对应的元素是否在新的集合中。//con是真正装载数据的数组。void get_sub(vector<int>  indexcon, int pos) {    /*函数名:get_sub(vector<int>  indexcon, int pos);      传入参数:记录某个元素是否在集合中的数组indexcon 和 pos处的元素是否在集合中      核心思想:在于对每个位置进行标记:子集有该元素和子集没有该元素。      函数作用:          1.最初是对下标数组indexcon进行标记:          例如:对于集合 1,2,3,数组indexcon          1 0 0 代表子集中有第一个元素没有第二三个元素。          0 0 0 代表没有任何元素->空集。          2.递归终点是:当对所有的下标情况标记完后,开始输出:如果为1就打印该位置处真正的元素值          如果为0则不打印。*/    if (pos == n)        //到达递归重点:根据indexcon标记情况进行打印输出。    {        printf("{ ");        for (int i = 0; i < pos; ++i)        {            if (indexcon[i])            {                cout << con[i] << " " ;            }        }        printf("}\n");        return;    }    indexcon[pos] = 0; //不取用pos位置处的元素    get_sub(indexcon, pos + 1);    indexcon[pos] = 1;//取用pos位置处的元素    get_sub(indexcon, pos + 1);}int main(int argc, char const *argv[]){    string length;    while (1) {        cout << "请您输入元素的个数(不要超过100000000):(输入q退出)" << endl;        cin >>  length;        if(length[0]=='q'&&length.size()==1){            cout << "感谢您的使用!"<< endl;            break;        }        int i = 0;        while ( '0' <= length[i] && length[i] <= '9')        {            i++;        }        if (i == (length.size() ))        {            n = atoi( length.c_str() );            if (n > 100000000)            {                cout << "对不起,您输入的数字太大。\n请您重新输入:" << endl;            } else if (n == 0)            {                cout << "对不起,您输入的数字为负数。\n请您重新输入:" << endl;            } else {                cout << "您输入集合的阶为: " << n << endl;                for (int i = 0; i < n; ++i)                {                    string temp;                    cin >> temp;                    con.push_back(temp);                    indexcon.push_back(0);//将下标数组全部初始化为0                }                printf("您输入的集合为:{ ");                for (int i = 0; i < n; ++i)                {                    cout << con[i] << " " << endl;                }                printf("}\n下面输出其子集:\n");                get_sub(indexcon, 0);                printf("\n");                printf("该集合总共有子集 %d 个\n", 1 << n);            }        } else {            cout << "请输入大于0的数字" << endl;        }        con.clear();        indexcon.clear();    }    return 0;}