集合类(并集、交集、差集操作)
昨日,朋友拿来一份有些问题的源代码,是一个集合类和几个集合操作函数(并集、交集、差集),帮忙改了一下,刚转C++不到半个月,因为只是为了算法竞赛而学C++,所以只好好学了C++偏向算法层的知识,类只是过了一遍,没有自己尝试写过,刚好拿来练练手,于是大刀阔斧的修改了起来,变动不是太大,都是细节有所改动(因为他的代码细节问题很多),大的体系没有变。
代码C++:
#include <iostream>
#include <string>
using namespace std;
const int MaxSize = 200;
// 集合类模板
template<class T>
class SeqList
{
public:
SeqList() // 无参构造函数
{
length = 0;
}
SeqList(T a, int n) // 带参构造函数
{
if (n > MaxSize)
{
throw "Error: The number of array elements is not valid in One!"; // 数组元素个数不合法
}
for (int i = 0; i < n; i++)
{
data[i] = a[i];
}
length = n; // 长度
}
SeqList(const SeqList &A) // A中元素的值不变
{
for(int i = 0; i < A.length; i++)
{
data[i] = A.data[i];
}
length = A.length;
}
int Length() // 求长度
{
return length;
}
char Get(int i) // 获取下标为i的元素
{
return data[i];
}
int Locate(T item) // 查找相同的元素
{
for (int i = 0; i <= length; i++)
{
if (data[i] == item)
{
return i + 1;
}
}
return 0;
}
void Insert(int i, char item) // 插入操作 在第i个位置插入一个元素item
{
int j;
if (length >= MaxSize)
{
throw "Error: Length is not lawful in Two!"; // 长度不合法
}
if (i < 1 || i > length + 1)
{
throw "Error: Place is not valid in Three!"; // 位置不合法
}
for (j = length; j >= i; j--)
{
data[j] = data[j - 1];
}
data[i - 1] = item;
length++;
}
T Delete(int i) // 删除并返回删除值操作 删除第i个位置的元素
{
int item, j;
if (length == 0)
{
throw "Error: Table is empty, can not delete elements!"; // 表为空,无法删除元素
}
if (i < 1 || i > length)
{
throw "Error: Place is not valid in Three!"; // 元素位置不合法
}
item = data[i - 1];
for (j = i; j < length; j++)
{
data[j-1]=data[j];
}
length--;
return item;
}
void display() // 输出操作
{
for (int i = 0; i < length; i++)
{
cout << data[i];
}
}
bool empty() // 判断是否为空
{
if (length == 0)
{
return true;
}
return false;
}
void clear() // 清理
{
length = 0;
}
private:
char data[MaxSize]; // 存储数据的数组
int length; // 表的长度
};
// 集合的并集集运算
template<class T>
SeqList<T> Union(SeqList<T> A, SeqList<T> B)
{
SeqList<T> C;
int m = 1;
int a = A.Length();
for (int b = 0; b <= B.Length(); b++)
{
A.Insert(a + b + 1, B.Get(b)); // 将B的元素插入到A的后面
}
for (char i = 'a'; i <= 'z'; i++)
{
for (int d = 0; d <= A.Length(); d++)
{
if (A.Get(d) == i) // 将组合后的元素和i比较
{
C.Insert(m, i); // 相同则插入
m++; // 不同则继续
break;
}
}
}
for (char u = 'a' - 32; u <= 'z' - 32; u++)
{
for (int d = 0; d <= A.Length(); d++)
{
if (A.Get(d) == u) // 将组合后的元素和i比较
{
C.Insert(m, u); // 相同则插入
m++; // 不同则继续
break;
}
}
}
return C;
}
// 集合的交集运算
template<class T>
SeqList<T> Toge(SeqList<T> A,SeqList<T> B)
{
SeqList<T> C;
int m = 1;
int flag = 0;
for (char i = 'a'; i <= 'z'; i++, flag = 0)
{
for (int a = 0; a <= A.Length(); a++)
{
if (A.Get(a) == i) // 将i与A中元素进行比较
{
for (int b = 0; b <= B.Length(); b++)
{
if (B.Get(b) == i) // 将i与B中元素进行比较
{
C.Insert(m, i); // 若都有i,则将其插入C
m++;
flag = 1;
break;
}
}
if(flag == 1)
{
break;
}
}
}
}
for (char u = 'a' - 32; u <= 'z' - 32; u++, flag = 0)
{
for (int a = 0; a <= A.Length(); a++)
{
if (A.Get(a) == u) // 将i与A中元素进行比较
{
for (int b = 0; b <= B.Length(); b++)
{
if (B.Get(b) == u) // 将i与B中元素进行比较
{
C.Insert(m, u); // 若都有i,则将其插入C
m++;
flag=1;
break;
}
}
if (flag == 1)
{
break;
}
}
}
}
return C;
}
// 集合的差集运算
template<class T>
SeqList<T> Subm(SeqList<T> A, SeqList<T> B)
{
SeqList<T> C;
int m = 1;
int flag = 0;
for (char i = 'a'; i <= 'z'; i++, flag = 0) // 这里i的范围如何修改,能够将大写的字母也加入范围中
{
for (int a = 0; a <= A.Length(); a++)
{
if (A.Get(a) == i) // 将i与A中元素进行比较
{
for (int b = 0; b <= B.Length(); b++)
{
if (B.Get(b) == i) // 继续与B中元素进行比较
{
flag = m;
}
}
if (flag == 0)
{
C.Insert(m, i);
m++;
break;
}
}
}
}
for (char u = 'a' - 32; u <= 'z' - 32; u++, flag = 0) // 这里i的范围如何修改,能够将大写的字母也加入范围中
{
for (int a = 0; a <= A.Length(); a++)
{
if(A.Get(a) == u) // 将i与A中元素进行比较
{
for(int b = 0; b <= B.Length(); b++)
{
if(B.Get(b) == u) // 继续与B中元素进行比较
{
flag = m;
}
}
if(flag == 0)
{
C.Insert(m, u);
m++;
break;
}
}
}
}
return C;
}
int main()
{
string a;
string b;
cout << "************集合a的元素为************:\n";
getline(cin, a); // 读取a的输入,因为输入中可能有空格,所以不用cin
cout << endl;
cout << "************集合b的元素为************:\n";
getline(cin, b); // 读取b的输入
cout << endl;
SeqList<string> A(a, (int)a.length()), B(b, (int)b.length()), C, D, E, F;
C = Union(A, B);
cout << "集合的并集为:";
C.display();
cout << endl;
D = Toge(A, B);
cout << "集合的交集为:";
D.display();
cout << endl;
E = Subm(B, A);
F = Subm(A, B);
cout << "集合的差集为:";
E.display();
F.display();
cout << endl;
return 0;
}
其实像这种非竞赛性的编程,我是极不愿意将命名空间std直接导入的,因为这样子有背命名空间存在的初衷。然而改一个人的代码真的是一个劳神的事情,源码的编码格式规范问题很严重,个人又有强迫症,先是花了半个小时将其代码规范了一下格式,因为我看着不是太规范的代码头疼……这也许是病吧!
命名规范和我不一样暂且能忍,毕竟也是一个比较流行且科学的命名规范,编码格式乱,我就忍不下去了……