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

来自于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

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
集合类
c语言实现简单数据库、链表c语言实现 简单、教师课堂评价语言集合、c语言求集合的并集、c语言集合的交并运算,以便于您获取更多的相关知识。

时间: 2024-10-10 01:26:32

C++简单集合类的实现方法_C 语言的相关文章

排列和组合算法的实现方法_C语言经典案例_C 语言

排列和组合算法是考查递归的常见算法,这两种算法能用递归简洁地实现. 本人在经过多次摸索和思考之后,总结如下,以供参考. 程序代码如下: #include <stdio.h> #include <stdlib.h> char array[] = "abcd"; #define N 4 #define M 3 int queue[N] = {0}; int top = 0; int flag[N] = {0}; void perm(int s, int n) { i

C#利用原图和水印图的重叠简单实现水印的方法_C#教程

本文实例讲述了C#利用原图和水印图的重叠简单实现水印的方法.分享给大家供大家参考,具体如下: 图片操作类 /// <summary> /// 获取一个图片按等比例缩小后的大小. /// </summary> /// <param name="maxWidth">需要缩小到的宽度</param> /// <param name="maxHeight">需要缩小到的高度</param> /// &l

C++实现简单的职工信息管理系统_C 语言

功能主模块描述 模块一:增加人员函数Add():增加职工基本信息. 模块二:删除人员函数Delete():删除指定的职工的基本信息以及薪酬. 模块三:修改人员函数Modify():修改指定的职工基本信息. 模块四:查询职工信息函数Search():查询指定的职工信息以及薪酬. 模块五:排序职工信息函数Sort():职工信息排序功能实现 模块六:基础数据设置函数Set():设置五类职位的基本薪酬. 模块七:数据存盘,载入函数Save()以及Load():储存职工基本信息,薪酬以及五类职位的基本薪酬

MFC程序对文件的处理方法_C 语言

对文件的处理是MFC程序设计中非常常见的应用.本文就以实例形式做一简单叙述.具体方法如下: 1.CFileDialog的应用 格式如下: CFileDialog::CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter =

C#使用winform简单导出Excel的方法_C#教程

本文实例讲述了C#使用winform简单导出Excel的方法.分享给大家供大家参考,具体如下: using Excel; 在项目中引入Excel.dll /// <summary> /// 导出Excel /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnEx

C语言简单实现计算字符个数的方法_C 语言

本文实例讲述了C语言简单实现计算字符个数的方法.分享给大家供大家参考.具体如下: char_counting.c如下: #include<stdio.h> int main() { long nc; nc = 0; while(getchar() != '0') { ++nc; } printf("%ld\n", nc); } 编译和使用下: 复制代码 代码如下: gcc char_counting.c -o char_counting.o   一种通常的调用方式: 复制代

C++实现哈夫曼树简单创建与遍历的方法_C 语言

本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法. 本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小. 据此构造出最优树算法如下: 哈夫曼算法: 1. 将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树.构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空 2. 在森林F中选取根节点权值最小二叉树,

Inline Hook(ring3)的简单C++实现方法_C 语言

C++的Inline Hook代码,采用了备份dll的方法,因此在自定义的函数中可以直接调用在内存中备份的dll代码,而不需要把函数头部改来改去.用SetWindowsHookEx程序的稳定性应该会增加许多. 需要注意的是,例子中没有把原函数的头部几个字节改回去是因为,程序很简单,仅仅测试了效果后便可以退出,没有其他的功能.实际应用中,还要在你注入的dll模块卸载时,把原函数的头几个字节改回去,以免影响到程序继续运行的稳定性.(因为注入的程序不是自己的,我们当然不可能知道它到底在何时.有多少个我

C语言求圆周率的简单实现方法_C 语言

本文实例讲述了C语言求圆周率的方法.分享给大家供大家参考,具体如下: #include <stdio.h> #include <math.h> void main() { int s; float n,t,pi; t=1,pi=0;n=1.0;s=1; while(fabs(t)>1e-6) { pi=pi+t; n=n+2; s=-s; t=s/n; } pi=pi*4; printf("pi=%10.6f/n",pi); } 此处得出的结果可精确到小数