C++简单集合类的实现方法

 更新时间:2020年4月25日 17:34  点击:1519

来自于C++程序设计的一个题目。实现一个集合类,要求实现以下4个操作。
 1.向集合中添加元素,如果集合中已存在元素则不添加
 2.从集合中移除元素,移除之前需要先判断集合中元素是否存在
 3.重载+运算符,用以实现集合的求并集运算
 4.重载*运算符,用以实现集合的求交集运算 

1.类的整体设计
该问题需要模拟实现集合类,我们可以使用数组来模拟集合,于是使用int items[100]用来存放集合中的数据。为了实现数组的遍历,这就需要一个整数用来表示数组中元素的个数,于是使用int number来表示数组中元素的个数;此外,为了实现题目的需求,设计以下四个函数:
 1).使用add_item(int item)成员函数向数组中添加元素
 2).使用remove_item(int item)成员函数向数组中移除元素
 3).重载operator+表示集合的求并集运算
 4).重载operator*表示集合的求交集运算
由于向集合添加元素之前,必须确保集合中不存在该元素;在从集合中移除元素之前,必须确保集合中存在该元素,因此添加is_exist(int item)方法用以判断集合中是否存在这个元素;此外为了显示集合,添加display()方法, 基本设计如下:

 class Set
{
public:
  int items[100]; //定义一个数组作为容器存放100个集合元素
  int number; //定义数字i表示集合中元素的个数
  //构造函数和析构函数
  Set() {
    this->number = 0;
    memset(this->items,0,sizeof(items));
  }
  //初始化方法
  int init(int items[], int num);
  //添加元素
  bool add_item(int item);
  //删除元素
  bool remove_item(int item);
  //求集合的并集
  Set operator+ (Set set2);
  //求集合的交集
  Set operator* (Set set2);
  //显示集合元素
  int display();
  //判断集合当中是否存在item,返回元素在集合中的位置,不存在返回-1
  int is_exist(int item);
}; 

2.构造函数

 Set() {
  this->number = 0;
  memset(this->items,0,sizeof(items));
} 

在构造函数中,我们对数组进行初始化,声明完数组之后,如果不进行初始化,数组元素是随机值,在C语言中,变量不进行初始化都会被分配随机值。为了避免这种情况,我们使用memset函数对数组items所有元素全部赋值为0;同时,由于此时数组中没有元素,即元素个数为0,我们的number也应当赋值为0. 

3.判断数组中是否包含元素 item

 int Set::is_exist(int item)
{
  for(int i=0; i< this->number; i++) {
    if(this->items[i] == item) {
      return i;
    }
  }
  return -1;
} 

该函数用于判断数组中是否存在item元素,如果存在就返回item元素的位置,如果不存在就返回-1. 判断方法非常简单,写一个for循环从items[0]-items[number-1]一个一个进行遍历。如果相等,直接返回i,此时i就是数组中item元素的位置;如果遍历完整个数组之后,都没有发现与item相等的数组元素,说明数组中不存在item这个元素,于是返回-1. 

4.向数组中添加元素

 bool Set::add_item(int item)
{
  if(is_exist(item) >= 0 || this->number >= 100) {
    return false;
  }
  this->items[this->number] = item;
  this->number++;
  return true;
} 

首先判断数组中是否存在该元素,如果存在则不能再向集合中添加元素,直接返回false,如果不存在,则向数组中的number所指向的那个位置添加该元素,然后number作为数组元素个数的指示器+1,这样就完成了添加元素。 

5.保护数组元素不被修改
写到这里,我们发现,数组元素个数指示器this->number,对于该问题的几个算法都起到了核心的作用,首先,我们依赖于数组元素个数指示器遍历数组,如果number值遭到修改,会导致无法遍历数组。举个例子来说,当我们调用下列语句以后:

 Set set1;
set1.add_item(1);
set1.add_item(2);
set1.add_item(3); 

集合set1中的数组items变为[1,2,3],数组元素个数指示器number=3,此时,如果我们还想向集合set1中添加元素20,我们需要利用number=3这个指示器,让set1.items[number]=20,并且让number+1以指向下一个位置,即number=4。但是如果用户手动修改number值,比如set1.number=50;此时,我们的number就不再能指示数组元素的正确位置,从而导致以上所有算法所依赖的number失效,因此,我们需要对数组本身,以及数组元素个数指示器number进行私有化,以避免用户随意篡改。于是:

 class Set
{
public:
  //构造函数和析构函数
  Set() {
    this->number = 0;
    memset(this->items,0,sizeof(items));
  }
  //初始化方法
  int init(int items[], int num);
  //添加元素
  bool add_item(int item);
  //删除元素
  int remove_item(int item);
  //求集合的并集
  Set operator+ (Set set2);
  //求集合的交集
  Set operator* (Set set2);
  //显示集合元素
  int display();
  //判断集合当中是否存在item,返回元素在集合中的位置,不存在返回-1
  int is_exist(int item);
private:
  int items[100]; //定义一个数组作为容器存放100个集合元素
  int number; //定义数字i表示集合中元素的个数
}; 

6. 从集合中移除元素

 bool Set::remove_item(int item)
{
  int pos = is_exist(item);
  if(pos == -1) return false;
  for(int i=pos; i< this->number-1; i++) {
    this->items[i] = this->items[i+1];
  }
  this->number--;
  return true;
} 

首先检查要移除的元素在结合中是否存在,如果不存在,则直接返回false;其次,定位到集合中元素的位置,然后从这个位置开始将集合中剩余的元素逐个前移,最后集合元素指示器-1,并返回true.

7. 求两个集合的交集

 Set Set::operator* (Set set2)
{
  Set result;
  for(int i=0; i< this->number; i++) {
    if(set2.is_exist(this->items[i]) >= 0) {
      result.items[result.number] = this->items[i];
      result.number++;
    }
  }
  return result;
} 

算法很简单,遍历集合A中的元素,对于A中的每一个元素判断在集合B中是否存在,如果存在就加入到集合C当中,最后返回集合C

8. 求两个集合的并集

 Set Set::operator+ (Set set2)
{
  Set result;
  for(int i=0; i<this->number; i++) {
    result.items[result.number] = this->items[i];
    result.number++;
  }
  for(int j=0; j<set2.number; j++) {
    if(result.is_exist(set2.items[j]) == -1) {
      result.items[result.number] = set2.items[j];
      result.number++;
    }
  }
  return result;
} 

首先遍历集合A,将集合A中的元素全部加到集合C当中,然后遍历集合B,对于B中的每一个元素,首先判断是否在A中存在,如果不存在则将其加入到集合C中,最终返回集合C

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ bitset用法

    这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 浅谈C++中的string 类型占几个字节

    本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
  • C++ Eigen库计算矩阵特征值及特征向量

    这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • C++ pair的用法实例详解

    这篇文章主要介绍了C++ pair的用法实例详解的相关资料,需要的朋友可以参考下...2020-04-25
  • VSCode C++多文件编译的简单使用方法

    这篇文章主要介绍了VSCode C++多文件编译的简单使用方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
  • C++中的循环引用

    虽然C++11引入了智能指针的,但是开发人员在与内存的斗争问题上并没有解放,如果我门实用不当仍然有内存泄漏问题,其中智能指针的循环引用缺陷是最大的问题。下面通过实例代码给大家介绍c++中的循环引用,一起看看吧...2020-04-25
  • C++随机点名生成器实例代码(老师们的福音!)

    这篇文章主要给大家介绍了关于C++随机点名生成器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++如何删除map容器中指定值的元素详解

    map容器是C++ STL中的重要一员,删除map容器中value为指定元素的问题是我们经常与遇到的一个问题,下面这篇文章主要给大家介绍了关于利用C++如何删除map容器中指定值的元素的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。...2020-04-25
  • C++ 约瑟夫环问题案例详解

    这篇文章主要介绍了C++ 约瑟夫环问题案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-15
  • C++中cin的用法详细

    这篇文章主要介绍了C++中cin的用法详细,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 基于C++中常见编译错误的总结详解

    本篇文章是对C++中的常见编译错误进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • c++优先队列(priority_queue)用法详解

    这篇文章主要介绍了c++优先队列(priority_queue)用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25