2 つのシーケンス テーブル (2 つの異なるセットを表す) が与えられた場合、シーケンス テーブルの基本操作を使用して、これら 2 つのセットの和集合、共通部分、および差分を実現します。
実行結果を次の図に示します。
順序テーブルの基本的な操作については別の記事で説明しましたので、ここでは詳細な説明は省略し、主に順序テーブルを使用してコレクションを実現する方法について説明します。
注: コレクションの要素は文字であるため、ElemType は char 型です。
コレクションの要素が数値の場合、ElemType を int 型に変更する必要があります。
#include <iostream.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int length;
} SqList; //定义线性表结构体类型
void InitList(SqList *&L) //引用型指针
{
L= new SqList;
/*分配存放线性表的空间*/
L->length=0;
}
//1.建立一个线性表
void CreateList(SqList *&L,ElemType a[],int n)
{
int i;
for (i=0;i<n;i++)
L->data[i]=a[i];
L->length=n;
}
//2.销毁线性表
void DestroyList(SqList *&L)
{
delete L;
}
//3.判定是否为空表
int ListEmpty(SqList *L)
{
return(L->length==0);
}
//4.求线性表的长度
int ListLength(SqList *L)
{
return(L->length);
}
//5.输出线性表
void DispList(SqList *L)
{
if (ListEmpty(L))
return;
for (int i=0;i<L->length;i++)
cout<<L->data[i]<<" ";
cout<<endl;
}
//6.求某个数据元素值GetElem(L,i,e)
int GetElem(SqList *L,int i,ElemType &e)
{
if (i<1 || i>L->length)
return 0;
e=L->data[i-1];
return 1;
}
//7.按元素值查找
int LocateElem(SqList *L, ElemType e)
{
int i=0;
while (i<L->length && L->data[i]!=e)
i++;
if (i>=L->length)
return 0;
else
return i+1;
}
//8.插入数据元素
int ListInsert(SqList *&L,int i,ElemType e)
{
int j;
if (i<1 || i>L->length+1)
return 0;
i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/
for (j=L->length;j>i;j--)/*将data[i]及后面元素后移一个位置*/
L->data[j]=L->data[j-1];
L->data[i]=e; //将新元素插入该位置
L->length++; /*顺序表长度增1*/
return 1;
}
//9.删除数据元素
int ListDelete(SqList *&L,int i,ElemType &e)
{
int j;
if (i<1 || i>L->length) return 0;
i--; /*将顺序表逻辑位序转化为elem下标即物理位序*/
e=L->data[i];
for (j=i;j<L->length-1;j++) L->data[j]=L->data[j+1];
/*将data[i]之后的元素前移一个位置*/
L->length--; /*顺序表长度减1*/
return 1;
}
連合
LA のすべての要素を LC に挿入し (CreateList 関数を使用することもできます)、次に LA が LB に持たない要素をフィルタリングする必要があります。
コアは if (!LocateElem(LA, e)) の意味を理解しています。つまり、LA で e (LB の要素) が見つからない場合は、e (LB の要素) を LC に挿入します。 LA e で見つかった場合、LC に e を挿入することはできません。
注: ++lena と lena++ の違いを区別してください
//求两顺序表的并
void unionList(SqList *LA,SqList *LB,SqList *&LC)
{
int lena,i;
ElemType e;
InitList(LC);
for (i=1;i<=ListLength(LA);i++)
/*将LA的所有元素插入到Lc中*/
{
GetElem(LA,i,e);
ListInsert(LC,i,e);
}
lena=ListLength(LA); /*求线性表的长度*/
int lenb=ListLength(LB);
for (i=1;i<=lenb;i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (!LocateElem(LA,e))
ListInsert(LC,++lena,e);
/*LA中不存在和e相同者,则插入到LC中*/
}
}
交差点
LC は空のリストです。LB の長さは LA の長さよりも大きいため、要素の欠落を避けるために、LB で for ループを拡張します。
コアは if (LocateElem(LA, e)) の意味を理解します。つまり、e (LB の要素) が LA で見つかった場合、e (LB の要素) が LC に挿入されます。 LA に e が見つからない場合、e を LC に挿入できません。
//求两顺序表的交
void InterList(SqList *LA,SqList *LB,SqList *&LC)
{
int j=0;ElemType e;
for (int i=1;i<=ListLength(LB);i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (LocateElem(LA,e))
ListInsert(LC,++j,e);
/*LA中存在和e相同者,则插入到LC中*/
}
}
差分セット
差分集合演算では、2つの集合の共通要素が打ち消し合うため、この性質に従って、LB内でLAと異なる要素を見つける必要があります。
if(!LocateElem(LA, e)) の理解は Union と同じです。
//求两顺序表的差
void DiffList(SqList *LA,SqList *LB,SqList *&LC)
{
int j=0;ElemType e;
for (int i=1;i<=ListLength(LB);i++)
{
GetElem(LB,i,e);
/*取LB中第i个数据元素赋给e*/
if (!LocateElem(LA,e))
ListInsert(LC,++j,e);
/*LA中存在和e不相同者,则插入到LC中*/
}
}
メイン機能
集合 AB と BA については、差分関数の仮パラメータ内の L1 と L2 の位置を交換するだけで済みます。
void main()
{
SqList *L1;InitList(L1);
ElemType a[4]={'A','B','C','D'};
CreateList(L1,a,4);
cout<<"线性表A的元素为:";DispList(L1);
cout<<endl;
SqList *L2;InitList(L2);
ElemType b[5]={'B','C','E','F','G'};
CreateList(L2,b,5);
cout<<"线性表B的元素为:";DispList(L2);
cout<<endl;
///求并集
SqList *L3;InitList(L3);
unionList(L1,L2,L3);
cout<<"A∪B:";
DispList(L3);
cout<<endl;
///求交集
SqList *L4;InitList(L4);
InterList(L1,L2,L4);
cout<<"A∩B:";
DispList(L4);
cout<<endl;
///求差集
InitList(L4);
DiffList(L2,L1,L4);
cout<<"A-B:";
DispList(L4);
cout<<endl;
///求差集
InitList(L4);
DiffList(L1,L2,L4);
cout<<"B-A:";
DispList(L4);
cout<<endl;
}