集合的基本运算: 依据集合运算规则,实现任意给定两个集合的交、并、差、笛卡儿积运算,和第一个集合的幂集,并显示运算结果。

来源:互联网 发布:数据营销有哪些 编辑:程序博客网 时间:2024/04/29 01:06
#include<iostream>
#include <cstring>
using namespace std;


struct s{  //定义用来表示集合的数据类型
int length;  //集合的元素数
char *elem;  //集合的元素
};
char p[100];
class Operators  //集合运算类
{
public:
s Input();
void Show(s A);
s Intersect(s A, s B);
s Union(s A, s B);
s Except(s A, s B);
void GetPowerSet(int i,s A);
void Descartes(s A, s B);
private:
void Sort(s A);
};


s Operators::Input()//集合的输入
{ s A;
cout << "请输入数组元素的个数:" << endl;
cin >> A.length;
A.elem = new char[A.length];
cout << "请输入" << A.length << "个元素:" << endl;
for(int i=0; i<A.length; i++){
cin >> A.elem[i];
}


return A;
}


s Operators::Intersect(s A, s B)//交集
{
s C;
int k,i,j;
C.length = A.length>B.length?B.length:A.length;
C.elem = new char[C.length];
    k=0;
for( i=0; i<A.length; i++){
for( j=0; j<B.length; j++){
if(A.elem[i]==B.elem[j]){
C.elem[k]=B.elem[j];
k++;
break;
}
}
}
C.length=k;
return C;
}


s Operators::Union(s A, s B)//并集
{
s C;
int i, j, k;  //k用来标记C中所赋值元素的个数
bool flag;    //标志位
    k=0;
C.length = A.length+B.length;
C.elem = new char[C.length];
for( i=0; i<A.length; i++){
C.elem[i] = A.elem[i];
k++;
}
for(j=0; j<B.length; j++){
flag=1;
for(i=0; i<A.length; i++){
if(B.elem[j]==A.elem[i]){
flag=0;
break;
}
}
if(flag){
C.elem[k]=B.elem[j];
k++;
            }
}
C.length = k;
return C;
}


s Operators::Except(s A, s B)//差集
{
s C;
int i, j, k;  //k用来标记C中所赋值元素的个数
bool flag;


C.length = A.length;
C.elem = new char[C.length];
k=0;
for(i=0; i<A.length; i++){
flag=1;
for(j=0; j<B.length; j++){
if(B.elem[j]==A.elem[i]){
flag=0;
break;
}
}
if(flag){
C.elem[k]=A.elem[i];
k++;
}
}
C.length = k;
return C;
}


void Operators::Descartes(s A, s B)//笛卡尔积
{
cout << "{";
for(int i=0; i<A.length; i++){
for(int j=0; j<B.length; j++){
cout << "<" << A.elem[i] << "," << B.elem[j] << ">" << " ";
}
}
cout << "}" << endl;
}


void Operators::Show(s A)
{
cout << "{ ";
for(int i=0;i<A.length;i++){
cout << A.elem[i] << " ";
}
cout << "}" << endl;
}


void Operators::GetPowerSet(int i,s A)//幂集
{
    int x;
    int k=0;
    int len = A.length;
    if(i >= len)
    {
        if(p[0]!=0)
            cout <<"{" <<p<<"}"<<"  ";
                    else
            cout << "{}" << endl;  // 表示空集
    }
    else
    {
        x = A.elem[i];
        k = strlen(p);
        p[k] = x;
        GetPowerSet(i+1, A);
        p[k] = 0;
        GetPowerSet(i+1, A);
    }
}
int main()
{
Operators o;
s X,Y,R;


    cout<<"请输入集合X"<<endl;
X = o.Input();
cout<<"请输入集合Y"<<endl;
Y = o.Input();


cout << "集合X∩Y=";
R = o.Intersect(X,Y);
o.Show(R);


cout << "集合X∪Y=";
R = o.Union(X,Y);
o.Show(R);


cout << "集合X-Y=";
R = o.Except(X,Y);
o.Show(R);


cout << "集合Y-X=";
R = o.Except(Y,X);
o.Show(R);


cout << "集合X*Y=";
o.Descartes(X,Y);


    cout<<"集合X的幂集= ";
    cout<<"{";
    o.GetPowerSet(0,X);
    cout<<"}";

}

补充:
 回溯法与树的遍历


求含n个元素的集合的幂集: 集合A的幂集是由集合A的所有子集所组成的集合。如:A = {1,2,3},则A的幂集p(A) = {{1,2,3}, {1,2}, {1,3}, {1}, {2,3}, {2}, {2}, 空集} 求幂集p(A)的元素的过程可看成是依次对集合A中元素进行“取”或“舍”的过程,并且可用一棵二叉树来表示过程中幂集元素的状态变化状况。 树中根结点表示幂集元素的初始状态(为空集); 叶子结点表示它的终结状态; 而第i(i=2,3,...,n-1)层的分支结点,则表示已对集合A中前i-1个元素进行了取/舍处理的当前状态(左分支表示“取”,右分支表示“舍”)。

如下图所示:


0 0
原创粉丝点击