Set中不存在重复元素,插入的时候需要遍历进行判断。
代码如下:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class AbsCollection{
protected:
int* iPtr; //指向数组的指针
int last; //数组最后一个元素的位置
int maxSize; //数组总体长度
public:
AbsCollection(int size = 100) {
maxSize = size;
iPtr = new int[maxSize];
last = -1;
};
virtual ~AbsCollection() {
if (iPtr != 0) {
delete[] iPtr;
iPtr = 0;
}
}
void OutputSet() { //输出集合中元素
for (int i = 0; i <= last; i++)
cout << iPtr[i] << " ";
cout << endl;
}
};
class Set :public AbsCollection
{
private:
char* fileName; //存放数据的文件
public:
Set(int size = 100, const char* szFileName = "");//从文件读取数据存入数组(要判断是否有重复元素)
virtual ~Set(); //析构函数,释放内存并将数据写入文件
void input(int x);
void erase(int x);
int isInSet(int x); //判断x是否已经存在于集合中
friend ostream& operator<<(ostream& os, Set& s);
void intersetion(Set& s);//求集合的交(*this与s的交,结果放在*this中)
void operator+(Set& s); //求集合的并(*this与s的并,结果放在*this中)
void diff(Set& s); //求集合的差(*this与s的差,结果放在*this中)
Set& operator=(Set& s); //赋值拷贝函数
void sort(); //将集合中元素从大到小排序
void setFile(const char* file) { //设置文件函数,避免多个对象在析构时写入一个文件(通过=或者使用默认参数构建对象时会出现这个问题)
fileName = const_cast<char*>(file);
}
};
Set::Set(int size, const char* szFileName):AbsCollection(size)
{
try
{
if (size < 1)
throw - 1; //抛出异常
fileName = const_cast<char*>(szFileName);
if (strlen(fileName) == 0)
return;
ifstream is(fileName);
if (is.is_open())
{
int t;
while (!is.eof())
{
is >> t;
//判断数据是否已经存在,过滤掉重复元素
int k = 0;
for (; k <= last; k++)
{
if (iPtr[k] == t)
break;
}
if (k > last) //没有重复数字
{
last++;
iPtr[last] = t;
}
}
is.close();
}
}
catch (int ) //捕获异常输出提示
{
cout << "Invalid Argument: size<10" << endl;
}
}
Set::~Set()
{
ofstream os(fileName); //数据写入文件
os << endl;
for (int i = 0; i <= last; i++)
os << iPtr[i] << " ";
os << endl;
os.close();
}
void Set::input(int x) //insert还是input?
{
if (last == maxSize - 1)
{
cout << "集合已满,插入失败!" << endl;
return;
}
if (!isInSet(x))
{
last++;
iPtr[last] = x;
cout << "插入成功!" << endl;
}
else
cout << x << "已在集合中,插入失败!" << endl;
}
void Set::erase(int x)
{
int flag = 0;
for (int i = 0; i <= last; i++)
{
if (iPtr[i] == x)
{
for (int j = i; j < last; j++)
iPtr[j] = iPtr[j + 1];
last--;
flag = 1;
cout << "删除成功!" << endl;
break;
}
}
if (flag == 0)
cout << x << "不再集合中,删除失败!" << endl;
}
int Set::isInSet(int x)
{
for (int i = 0; i <= last; i++)
{
if (iPtr[i] == x)
{
return 1;
}
}
return 0;
}
ostream& operator<<(ostream& os, Set& s)
{
for (int i = 0; i <= s.last; i++)
os << s.iPtr[i] << " ";
return os;
}
void Set::intersetion(Set& s)//求集合的交(*this与s的交,结果放在*this中)
{
int i = 0, j = 0;
for (; i <= last; i++)
{
if (s.isInSet(iPtr[i])) //同时在*this和s中
{
iPtr[j++] = iPtr[i];
}
}
last = j - 1;
}
void Set::operator+(Set& s) //求集合的并(*this与s的并,结果放在*this中)
{
for (int i = 0; i <= s.last; i++)
{
if (!isInSet(s.iPtr[i])) //s中的元素不再*this中,则插入*this中
{
if (last < maxSize-1)
{
last++;
iPtr[last] = s.iPtr[i];
}
else
cout << "集合已满,插入失败!" << endl;
}
}
}
void Set::diff(Set& s) //求集合的差(*this与s的差,结果放在*this中)
{
//删除*this中与s中相同的
int t = last;
for (int i = 0; i <= last; i++)
{
if (s.isInSet(iPtr[i]))
{
for (int j = i; j < last; j++)
iPtr[j] = iPtr[j + 1];
last--;
i--; //因为删除后,所有数据都前移1位,这里为了抵消for循环的i++
}
}
}
Set& Set::operator=(Set& s) //赋值拷贝函数
{
delete[] iPtr;
maxSize = s.maxSize;
fileName = const_cast<char*>(s.fileName);
iPtr = new int[maxSize];
for (int i = 0; i <= s.last; i++)
iPtr[i] = s.iPtr[i];
last = s.last;
return *this;
}
void Set::sort() //将集合中元素从大到小排序
{
int t;
for (int i = 0; i < last; i++)
{
for (int j = 0; j < last - i; j++)
{
if (iPtr[j] < iPtr[j + 1])
{
t = iPtr[j];
iPtr[j] = iPtr[j + 1];
iPtr[j + 1] = t;
}
}
}
}
int main()
{
Set s1(20, "f1.txt");
cout << "从f1.txt中读取数据构建Set对象s1,对象内容为:" << endl;
s1.OutputSet();
//插入数据
int x;
cout << "请输入要插入的数据:";
cin >> x;
s1.input(x);
//删除
cout << "请输入要删除的数据:";
cin >> x;
s1.erase(x);
//是否在集合中
cout << "请输入一个数x,判断x是否在集合中:";
cin >> x;
if (s1.isInSet(x))
cout << x << "在集合s1中" << endl;
else
cout << x << "不在集合s1中" << endl;
cout << endl << "操作完成后,s1中的内容为:" ;
cout << s1 << endl;
//构建集合对象s2
cout << "从f2.txt读取数据构建集合对象s2:" << endl;
Set s2(20,"f2.txt");
cout << "集合对象s2中的数据元素为:";
cout << s2 << endl; //或者 s2.OutputSet();
//使用=复制s1,以便计算交集、并集和差集
Set s3(20), s4(20);
s3 = s1;
s4 = s1;
s3.setFile("f3.txt");
s4.setFile("f4.txt");
cout << "使用=复制s1,构建集合对象s3、s4" << endl << endl;
//s1与s2的交集
cout <<"s1: "<< s1 << endl;
cout <<"s2: "<< s2 << endl;
s1.intersetion(s2);
cout << "s1与s2的交集:" << endl;
cout << s1 << endl;
//s3与s2的并集
cout << endl << endl;
cout << "s3: " << s3 << endl;
cout << "s2: " << s2 << endl;
s3 + s2; //+的返回值是void类型,结果保存到+前面的对象中,所以这里不能用=来保存结果
cout << "s3与s2的并集:" << endl;
cout << s3 << endl;
//s4与s2的差集
cout << endl << endl;
cout << "s4: " << s4 << endl;
cout << "s2: " << s2 << endl;
cout << "s4与s2的差集:" << endl;
s4.diff(s2);
cout << s4 << endl;
cout << endl << "集合s4的内容:" << endl;
cout << s4 << endl;
cout << "集合s4排序后:" << endl;
s4.sort();
cout << s4 << endl;
return 0;
//程序结束后调用s1-s4的析构函数,将结果写入文件
}
class 类名称
{
public:
外部成员
protected:
保护型成员
private:
私有成员
};
其中,public,protected和private都是对类成员的不同访问权限控制
类的成员函数定义必须写在类内
我可以给您提供一些关于如何使用c++实现集合的综合运用的建议。
在C++中,可以通过各种数据结构实现集合。具体而言,可以使用数组、链表、栈、队列等。其中,数组的查询速度很快,但是插入和删除速度较慢;链表的插入和删除速度很快,但是查询速度较慢;栈和队列则可以通过不同的方式来实现集合操作。
在实现集合的综合运用中,主要需要实现以下几个操作:
可以使用数组、链表等数据结构来存储集合中的元素。初始化集合时,需要定义一个数组或链表,并将所有元素插入到其中。
例如,使用数组来实现一个集合:
#include <iostream>
using namespace std;
const int MAX_SIZE = 100;
class Set {
private:
int elements[MAX_SIZE];
int size;
public:
Set() {
size = 0;
}
void add(int x) {
elements[size++] = x;
}
void output() {
for (int i = 0; i < size; i++) {
cout << elements[i] << " ";
}
cout << endl;
}
};
int main() {
Set set;
set.add(1);
set.add(2);
set.add(3);
set.output();
return 0;
}
可以使用双指针法来实现两个有序集合的交集。具体而言,定义两个指针i和j,并将它们分别指向两个集合的开头。如果第一个集合的元素小于第二个集合的元素,则将指针i向后移动一位;如果第二个集合的元素小于第一个集合的元素,则将指针j向后移动一位;如果两个集合的元素相等,则将该元素加入到交集中,并将指针i和j都向后移动一位。
例如,实现两个有序集合的交集:
#include <iostream>
using namespace std;
const int MAX_SIZE = 100;
class Set {
private:
int elements[MAX_SIZE];
int size;
public:
Set() {
size = 0;
}
void add(int x) {
elements[size++] = x;
}
void output() {
for (int i = 0; i < size; i++) {
cout << elements[i] << " ";
}
cout << endl;
}
Set intersect(Set& other) {
Set result;
int i = 0;
int j = 0;
while (i < size && j < other.size) {
if (elements[i] < other.elements[j]) {
i++;
}
else if (other.elements[j] < elements[i]) {
j++;
}
else {
result.add(elements[i]);
i++;
j++;
}
}
return result;
}
};
int main() {
Set set1;
set1.add(1);
set1.add(2);
set1.add(3);
Set set2;
set2.add(2);
set2.add(3);
set2.add(4);
Set result = set1.intersect(set2);
result.output();
return 0;
}
可以使用哈希表来实现两个集合的并集。具体而言,将两个集合中的元素哈希到一个哈希表中,然后输出哈希表中的所有元素。
例如,实现两个集合的并集:
#include <iostream>
#include <unordered_set>
using namespace std;
const int MAX_SIZE = 100;
class Set {
private:
int elements[MAX_SIZE];
int size;
public:
Set() {
size = 0;
}
void add(int x) {
elements[size++] = x;
}
void output() {
for (int i = 0; i < size; i++) {
cout << elements[i] << " ";
}
cout << endl;
}
unordered_set<int> get_set() {
unordered_set<int> result;
for (int i = 0; i < size; i++) {
result.insert(elements[i]);
}
return result;
}
};
int main() {
Set set1;
set1.add(1);
set1.add(2);
set1.add(3);
Set set2;
set2.add(3);
set2.add(4);
set2.add(5);
unordered_set<int> result_set;
unordered_set<int> set1_set = set1.get_set();
for (int i = 0; i < set1.size; i++) {
result_set.insert(set1.elements[i]);
}
for (int i = 0; i < set2.size; i++) {
if (set1_set.count(set2.elements[i]) == 0) {
result_set.insert(set2.elements[i]);
}
}
for (int x : result_set) {
cout << x << " ";
}
cout << endl;
return 0;
}
集合的差集可以通过对原始集合进行一些操作来实现。例如,可以将第一个集合中不属于第二个集合的元素添加到新的集合中。
例如,实现两个集合的差集:
#include <iostream>
#include <unordered_set>
using namespace std;
const int MAX_SIZE = 100;
class Set {
private:
int elements[MAX_SIZE];
int size;
public:
Set() {
size = 0;
}
void add(int x) {
elements[size++] = x;
}
void output() {
for (int i = 0; i < size; i++) {
cout << elements[i] << " ";
}
cout << endl;
}
unordered_set<int> get_set() {
unordered_set<int> result;
for (int i = 0; i < size; i++) {
result.insert(elements[i]);
}
return result;
}
};
int main() {
Set set1;
set1.add(1);
set1.add(2);
set1.add(3);
Set set2;
set2.add(3);
set2.add(4);
set2.add(5);
unordered_set<int> set1_set = set1.get_set();
unordered_set<int> set2_set = set2.get_set();
unordered_set<int> result_set;
for (int x : set1_set) {
if (set2_set.count(x) == 0) {
result_set.insert(x);
}
}
for (int x : result_set) {
cout << x << " ";
}
cout << endl;
return 0;
}
希望上述建议可以对您有所帮助。