通用库动态集合模板类

 

/**////通用库动态集合模板类
/**//**
 * 通用库4.0版<br>
 * 这是一个集合类,这个类的元素存放是一个有序的数组。这个类的元素查找方法为二分查找。
 * 这个类提供了类相关的所有功能.集合的方法有交集*,并集+,差集-,除此之后,还有*=,+=,-=等对应方法.
 * 集合类通过Contains,检查指定元素是否在集合中
 * @author zdhsoft(祝冬华)
 * @version 4.0
 * @date 2008-04-01
 * @file xset.h
 */
#ifndef _X_SET_H_
#define _X_SET_H_
#include <xarray.h>
namespace zdh
...{
 /**////基于数组的集合模板类
 template<class T,class Array = XArray<T> >
 class XSet
 ...{
 public:
  typedef T ElementType;
  typedef ElementType * PElementType;
 public:
  /**////缺省构造函数
  XSet()
  ...{}
  /**////缺省拷贝构造函数
  XSet(const XSet<T,Array> & aSet)
   :m_Data(aSet.m_Data)
  ...{}
  /**////指定最小值和最大值的构函造函数
  XSet(const T & vMin,const T & vMAX,XInt aRepareLength = 0);
  /**////取有效的数组元素个数
  XInt getLength() const
  ...{
   return  m_Data.getLength();
  }
  /**////判断集合是否为空
  /**//**
      @return 返回检查的结果
        - true 表示集合为空
        - false 表示集合不为空
  */
  bool isEmpty() const 
  ...{
   return m_Data.isEmpty();
  }
  /**////是否为第一个下标
  /**//**
      @param aIndex 被检查的下标
      @return 返回检查的结果 
        - true 表示是第一个下标
        - false 表示不是第一个下标
  */
  bool isFirstIndex(XInt aIndex) const
  ...{
   return m_Data.isFirstIndex(aIndex)
  }
  /**////是否为最后一个下标
  /**//**
      @param aIndex 被检查的下标
      @return 返回检查的结果 
        - true 表示是最后一个下标
        - false 表示不是最后一个下标
  */
  bool isLastIndex(XInt aIndex) const
  ...{
   return m_Data.isLastIndex(aIndex);
  }
  /**////是否为有效的下标
  /**//**
      @param aIndex 被检查的下标
      @return 返回检查的结果 
        - true 表示有效下标
        - false 表示无效下标
  */
  bool isValidIndex(XInt aIndex) const
  ...{
   return m_Data.isValidIndex(aIndex);
  }
  /**////取当前集合的容量
  XInt getCapacity() const
  ...{
   return m_Data.getCapacity();
  }
  /**////取指定下标的集合元素
  /**//**
      @param [in] aIndex 指定的下标
      @return 返回指定下标的引用
      @exception 如果发生越界,则抛出XEOutOfRange异常
  */
  const T & getElement(XInt aIndex) const
  ...{
   return m_Data.getElement(aIndex);
  }
  /**////确认最小容量
  /**//**
      确认最小容量,如果容量不够,则扩展容量
      @param [in] minimumCapacity 确认的最小容量
  */
  void ensureCapacity(XInt minimunCapacity)
  ...{
   m_Data.ensureCapacity(minimunCapacity);
  }
  /**////取第一个下标
  /**//**
      @return 返回第一个下标
        - ARRAY_INVALID_INDEX 表示无效下标
        - 0 表示有效第一个下标
  */
  XInt getFirstIndex() const
  ...{
   return m_Data.getFirstIndex();
  }
  /**////取最后一个下标
  /**//**
      @return 返回最后一个下标
        - ARRAY_INVALID_INDEX 表示无效下标
        - >=0 表示有效最后一个下标
  */
  XInt getLastIndex() const 
  ...{
   return m_Data.getLastIndex();
  }
  /**////取集合的最大容量
  XInt getMaxCapacity() const
  ...{
   return m_Data.getMaxCapacity();
  }
  /**////清除集合
  void Clear()
  ...{
   m_Data.Clear();
  }
  /**////向集合中加入一个元素
  XSet<T,Array> & operator << (const T & data) //加入一个元素
  ...{
   Add(data);
   return *this;
  }
  /**////向集合中删除一个元素
  XSet<T,Array> & operator >> (const T & data) //删除一个元素
  ...{
   Remove(data);
   return *this;
  }
  /**////向集合加入一个集合的元素
  XSet<T,Array> & operator << (const XSet<T,Array> & rhs) //加入一个集合中的有元素
  ...{
   Add(rhs);
   return *this;
  }
  /**////向集合中,删除一个集合的元素
  XSet<T,Array> & operator >> (const XSet<T,Array> & rhs) //删除一个集合中的有元素
  ...{
   Remove(rhs);
   return *this;
  }
  /**////向集合中加入一个元素
  /**//**
      @param data 被加入的元素
  */
  void Add(const T & data)     //加入一个元素
  ...{
   _Insert(data);
  }
  /**////向集合中,加入一个集合的元素
  void Add(const XSet<T,Array> & rhs); //加入一个集合中的有元素
  /**////删除一个指定的元素
  void Remove(const T & data)  //删除一个元素
  ...{
   XInt iIndex = _Contains(data);
   if( iIndex != ARRAY_INVALID_INDEX ) m_Data.Remove(iIndex);
  }
  /**////删除另一个集合中有的元素
  void Remove(const XSet<T,Array> & rhs);//删除一个集合中的有元素
  /**////检查元素是否在这个集合中
  bool Contains(const T & data) const
  ...{
   return _Contains(data) != ARRAY_INVALID_INDEX;
  }
  /**////检查指定集合的元素是否在这个集合中
  bool Contains(const XSet<T,Array> & rhs) const;
  /**////重载[]运算符
  /**//**
      重载[]运算符,取指定下标的集合元素
      @param Index 下标值
      @return 返回指定下标的元素的常量引用
  */
  const T & operator[](XInt Index) const
  ...{
   return m_Data[Index];
  };
  /**////缺省拷贝复制函数
  XSet<T,Array> & operator = (const XSet<T,Array> & rhs)
  ...{
   if( this != & rhs ) 
   ...{
    m_Data = rhs.m_Data;
   }
   return *this;
  }
  /**////两个集合差集的运算
  XSet<T,Array> operator-(const XSet<T,Array> & rhs) const; //差集
  /**////两个集合并集的运算
  /**//**
      @param rhs 并集集合
      @return 返回并集运算结果
  */
  XSet<T,Array> operator+(const XSet<T,Array> & rhs) const //并集
  ...{
   XSet<T,Array> aSet(*this);
   aSet.Add(rhs);
   return aSet;
  }
  /**////两个集合交集的运算
  XSet<T,Array> operator*(const XSet<T,Array> & rhs) const; //交集
  /**////集合的子集运算
  XSet<T,Array> SubSet(const T & MinData,const T & MaxData) const;
  /**////集合差集运算
  XSet<T,Array> & operator-=(const XSet<T,Array> & rhs); //差集
  /**////集合并集运算
  XSet<T,Array> & operator+=(const XSet<T,Array> & rhs) //并集
  ...{
   Add(rhs);
   return *this;
  }
  /**////集合交集运算
  XSet<T,Array> & operator*=(const XSet<T,Array> & rhs); //交集
  /**////取指定元素的下标
  /**//**
      @param data 指定的元素
      @return 返回指定元素的下标
        - ARRAY_INVALID_INDEX 表示未找到这个元素
        - 其它值,表示该元素的下标
  */
  XInt getIndex(const T & data) 
  ...{ 
   return _Contains(data); 
  }
  /**////比较两个集合是否相同
  bool operator == (const XSet<T,Array> & rhs) const;
  /**////比较两个集合是否不相同
  bool operator != (const XSet<T,Array> & rhs) const;
 private:
  /**////检查这个集合是否包含指定元素
  XInt _Contains(const T & data) const;//采用二分查找
  /**////向集合中插入一个元素
  void _Insert(const T & data); //插入一个元素
 private:
  Array m_Data;//存放集合数据的数组
 };
 //----------------------------------------------------------------------------
 /**//**
     向集合中加入另一个集合的元素
     @param rhs 加入的元素集合
 */
 template<class T,class Array>
 void XSet<T,Array>::Add(const XSet<T,Array> & rhs)
 ...{
  if( this != &rhs )
  ...{
   for( XInt i = rhs.getLength() - 1; i >= 0; i-- ) Add( rhs[i] );
  }
 }
 //----------------------------------------------------------------------------
 /**//**
     @param rhs 要删除元素的集合
 */
 template<class T,class Array>
 void XSet<T,Array>::Remove(const XSet<T,Array> & rhs)
 ...{
  if( this != &rhs )
  ...{
   for(XInt i = rhs.getLength()-1 ; i>=0; i--) Remove(rhs[i]);
  }
  else Clear();
 }
 //----------------------------------------------------------------------------
 /**//**
     检查这个集合是否包含指定元素。使用的查找的方法是二分查找
     @param data 被检查的元素
     @return 被检查到的元素的下标
       - ARRAY_INVALID_INDEX 表示没有找到这个元素
       - 其它>=0的值,表示找到了
 */
 template<class T,class Array>
 XInt XSet<T,Array>::_Contains(const T & data) const
 ...{
  XInt Low = 0,High = m_Data.getLength() - 1 ,Mid;
  while( Low <= High )
  ...{
   Mid = (Low + High) /2;
   const T & Tmp = m_Data[Mid];
   if( Tmp == data ) return Mid;
   else if ( Tmp > data ) High = Mid -1;
   else Low = Mid + 1;
  }
  return ARRAY_INVALID_INDEX;
 }
 //----------------------------------------------------------------------------
 /**//**
     检查当前集合,是否包括指定的集合
     @param rhs 要检查的集合
     @return 检查的结果
       - true 表示包含指定的集合
       - false 表示不包含指定的集合
 */
 template<class T,class Array>
 bool XSet<T,Array>::Contains(const XSet<T,Array> & rhs) const
 ...{
  if( this == &rhs ) return true;
  if( rhs.isEmpty() ) return true;
  if( rhs.getLength() > getLength() ) return false;
  for(XInt i = rhs.getLength()-1; i >=0 ; i--)
  ...{
   if( !Contains(rhs[i]) ) return false;
  }
  return true;
 }
 //----------------------------------------------------------------------------
 /**//**
     向集合中插入一个元素。这方法是私有方法,仅供XSet内部调用
     @param data 要插入的元素
 */
 template<class T,class Array>
 void XSet<T,Array>::_Insert(const T & data)
 ...{
  XInt iLength = m_Data.getLength();
  if( iLength <= 0 ) m_Data.Append( data );
  else
  ...{
   //查找插入的位置
   XInt Low = 0,High = iLength-1,Mid;
   while( Low <= High )
   ...{
    Mid = (Low + High) /2;
    const T & Tmp = m_Data[Mid];
    if( Tmp == data ) return; //如果已有该元素,则返回
    else if ( Tmp > data ) High = Mid -1;
    else Low = Mid + 1;
   }
   if( m_Data[Mid] > data ) m_Data.Insert(Mid,data);
   else m_Data.Insert(Mid+1,data);
  }
 }
 //----------------------------------------------------------------------------
 /**//**
     指定最小值和最大值的构造函数
     @param vMin 最小值
     @param vMax 最大小
     @param aRepareLength 准备的数组大小
 */
 template<class T,class Array>
 XSet<T,Array>::XSet(const T & vMin,const T & vMax,XInt aRepareLength)
 ...{
  ensureCapacity(aRepareLength); //确定容量
  if( vMin > vMax )
  ...{
   for( T i = vMax; i<=vMin; ++i ) m_Data.Append(i);
  }
  else
  ...{
   for( T i = vMin; i<=vMax; ++i ) m_Data.Append(i);
  }
 }
 //----------------------------------------------------------------------------
 /**//**
     集合的差集操作,这个操作,会返回一个新的集合,这个集合中的元素,分是属于两个集合
    的元素,但又不是两个集合的共有元素
     @param rhs 另一个差集集合
     @return 返回两个集合差集的结果
 */
 template<class T,class Array>
 XSet<T,Array> XSet<T,Array>::operator - (const XSet<T,Array> & rhs) const
 ...{
  XSet<T,Array> ret;
  if( this != &rhs )
  ...{
   for(XInt i = m_Data.getLength() - 1; i>=0; i--)
   ...{
    const T & data = m_Data[i];
    if( !rhs.Contains( data ) ) ret.Add( data );
   }
   for(XInt i = rhs.getLength() - 1; i>=0 ; i--)
   ...{
    const T & data = m_Data[i];
    if( !Contains( data ) ) ret.Add( data );
   }
  }
  return ret;
 }
 //----------------------------------------------------------------------------
 /**//**
     集合的交集操作,这个操作,会返回一个新的集合,这个集合中的元素,是两个集合的共有
     的元素
     @param rhs 交集集合
     @return 返回交集运算的结果
 */
 template<class T,class Array>
 XSet<T,Array> XSet<T,Array>::operator*(const XSet<T,Array> & rhs) const
 ...{
  XSet<T,Array> ret;
  if( this != & rhs )
  ...{

   for(XInt i = m_Data.getLength() - 1; i >= 0; i-- )
   ...{
    const T & data = m_Data[i];
    if( rhs.Contains( data ) ) ret.Add ( data );
   }
  }
  else ret = rhs;
  return ret;
 }
 //----------------------------------------------------------------------------
 /**//**
     比较两个集合是否相同
     @param rhs 比较的集合
     @return 返回比较的结果
       - true 表示两个集合相同
       - false 表示两个集合不相同
 */
 template<class T,class Array>
 bool XSet<T,Array>::operator == (const XSet<T,Array> & rhs) const
 ...{
  if( this == &rhs ) return true;
  if( rhs.getLength() != m_Data.getLength() ) return false;

  for(XInt i = m_Data.getLength() -1 ;i >= 0;i--)
  ...{
   if( m_Data[i] != rhs[i] ) return false;
  }
  return true;
 }
 //----------------------------------------------------------------------------
 /**//**
 如果两个集合是否不相同
     @param rhs 比较的集合
     @return 返回比较的结果
       - true 表示两个集合不相同
       - false 表示两个集合相同
 */
 template<class T,class Array>
 inline bool XSet<T,Array>::operator != (const XSet<T,Array> & rhs) const
 ...{
  return !operator == (rhs);
 }
 //----------------------------------------------------------------------------
 /**//**
     两个集合做差集远算后,并将结果放到当前集合中
     @param rhs 差集集合
     @return 返回当前集合的引用
 */
 template<class T,class Array>
 XSet<T,Array> & XSet<T,Array>::operator-=(const XSet<T,Array> & rhs)
 ...{
  if( this == &rhs ) Clear();
  else
  ...{
   if( !rhs.isEmpty() )
   ...{
    if( isEmpty() ) operator = (rhs);
    else
    ...{
     XSet<T,Array> tmp = *this;
     tmp *= rhs;      //取得两个集合的交集
     *this += rhs;    //取得两个集合的并集
     Remove(tmp);     //删除两个集合的交集
    }
   }
  }  
  return *this;
 }
 //----------------------------------------------------------------------------
 /**//**
     两个集合做交集远算后,并将结果放到当前集合中
     @param rhs 交集集合
     @return 返回当前集合的引用
 */
 template<class T,class Array>
 XSet<T,Array> & XSet<T,Array>::operator*=(const XSet<T,Array> & rhs)
 ...{
  if( this != &rhs )
  ...{
   if( rhs.isEmpty() ) Clear(); //如果rhs集合为空,则交集为空
   else //如果当前集合不为空
   ...{
    if( !isEmpty() ) //如果两个集合都不为空
    ...{
     
     for(XInt i = m_Data.getLength() - 1; i>=0; i--)
     ...{
      if( !rhs.Contains(m_Data[i])) m_Data.Remove(i); //如果指定的元素不存在,则删除
     }
    }
   }
  }
  return *this;
 }
 //----------------------------------------------------------------------------
 /**//**
     从当前集合中,取出指定范围的子集中的元素,并做为一个新的集合返回,返回的子集是[MinData,MaxData]

     @param MinData 最小的元素
     @param MaxData 最大的元素
     @return 返回子集结果
 */
 template<class T,class Array>
 XSet<T,Array> XSet<T,Array>::SubSet(const T & MinData,const T & MaxData) const
 ...{
  const T *max=&MaxData;
  const T *min=&MinData;
  if( MinData > MaxData )
  ...{
   max = &MinData;
   min = &MaxData;
  }
  XSet<T,Array> retSet;
  XInt iLength = m_Data.getLength();
  for(XInt i = 0; i<iLength;i++)
  ...{
   const T & data = m_Data[i];
   if( (data >= *min) && (data <= *max) ) retSet.m_Data.Append(data);
  }
  return retSet;
 }
}
#endif
 

时间: 2024-09-19 08:18:23

通用库动态集合模板类的相关文章

通用库动态数组模板类

///通用库动态数组模板类/** * 通用库4.0版<br> * 这里定义了一个动态数组模板类.这次将以前的XDyanmicArray和XArray合并成一个XArray了. * 除此之外,增加了数组元素初始化为0的操作,同时,会执行数组元素默认的构造函数和析造函数. * 同样,这个动态数组比较适合元数据中没有指针数据成员的元素或额外使用资源的元素. * 对于使用对象为数组元素的数组,可以使用XObjectArray模板类,可以有效的解决问题. * @author zdhsoft(祝冬华) *

通用库动态对象数组模板类

///通用库动态对象数组模板类/** * 通用库4.0版<br> * 这里定义了一个动态对象数组模板类.这个数组适合不能移动的对象或含有指针或被引用的对象. * 特点就是,不会像XArray中一样,调整数组容量,会造所有数组元素地址都发生变化. * @author zdhsoft(祝冬华) * @version 4.0 * @date 2008-03-01 * @file xobjectarray.h */#ifndef _X_OBJECT_ARRAY_H_#define _X_OBJECT_

通用库Map模板类

///通用库Map模板类/** * 通用库4.0版<br> * 这是一个映射类,提供基本的Map功能,这个映射是基于动态有序数组,查找方式用二分查找.<br> * 主要的方法有operator[],getValue(),getKey(),operator=,getLength(),RemoveByKey(),RemoveByIndex(),Clear(),Contains()等方法<br> * 除此之外,还提了一些类数组的方法.getCapaity(),getFirst

ASP 通用模板类

模板 ASP 通用模板类. 适合存在较少循环的模板.未实现内部循环,需要使用正则表达式,较浪费资源和时间,如需使用可参考这篇文章. 特性可设定私有缓存或公共缓存,提高效率可自由选择使用 Stream 组件或 FSO 组件支持自定义文件编码可保存文件 属性 Name文本,该模板名称,主要用于使用公共缓存时区分不同模板. Format文本,文件编码类型,可设置值. Object文本,使用组件,可设置值: StreamFSO PublicCache布尔值,使用公共缓存,开启时模板文件将保存到Appli

ASP通用模板类

  ASP 通用模板类. 适合存在较少循环的模板.未实现内部循环,需要使用正则表达式,较浪费资源和时间,如需使用可参考这篇文章. 特性 可设定私有缓存或公共缓存,提高效率 可自由选择使用 Stream 组件或 FSO 组件 支持自定义文件编码 可保存文件 属性 Name 文本,该模板名称,主要用于使用公共缓存时区分不同模板. Format 文本,文件编码类型,可设置值. Object 文本,使用组件,可设置值: Stream FSO PublicCache 布尔值,使用公共缓存,开启时模板文件将

C++标准库和标准模板库

C++强大的功能来源于其丰富的类库及库函数资源.C++标准库的内容总共在50个标准头文件中定义.在C++开发中,要尽可能地利用标准库完成.这样做的直接好处包括:(1)成本:已经作为标准提供,何苦再花费时间.人力重新开发呢:(2)质量:标准库的都是经过严格测试的,正确性有保证:(3)效率:关于人的效率已经体现在成本中了,关于代码的执行效率要相信实现标准库的大牛们的水平:(4)良好的编程风格:采用行业中普遍的做法进行开发. 在C++程序设计课程中,尤其是作为第一门程序设计课程,我们注重了语法.语言的

实现真正意义上的二维动态数组模板

我们可以通过动态数组的反例来确定动态数组应该具有哪些特性.大家都知道以下的方式是定义一个静态数组. int iCount[10]; int iCount[10][10]; 从上面可以看出,定义了静态数组之后,无论程序如果使这个数组,该数组在内存中所占空间的大小,位置是确定不变的. 我们可以得出结论,对于编译器,静态数组的大小和空间是已知的,因此编译器可以自动为该数组分配空间.具体情况是:如果你定义了一个全局数组,编译器将在数据区为你的数组分配一个空间:如果是个局部数组(比如定义在某一个局数中),

OpenStack 实现技术分解 (7) 通用库 — oslo_config

目录 目录 前文列表 扩展阅读 osloconfig argparse cfgpy class Opt class ConfigOpts CONF 对象的单例模式 前文列表 OpenStack 实现技术分解 (1) 开发环境 - Devstack 部署案例详解 OpenStack 实现技术分解 (2) 虚拟机初始化工具 - Cloud-Init & metadata & userdata OpenStack 实现技术分解 (3) 开发工具 - VIM & dotfiles Open

c++模板类

理解编译器的编译模板过程 如何组织编写模板程序 前言常遇到询问使用模板到底是否容易的问题,我的回答是:"模板的使用是容易的,但组织编写却不容易".看看我们几乎每天都能遇到的模板类吧,如STL, ATL, WTL, 以及Boost的模板类,都能体会到这样的滋味:接口简单,操作复杂. 我在5年前开始使用模板,那时我看到了MFC的容器类.直到去年我还没有必要自己编写模板类.可是在我需要自己编写模板类时,我首先遇到的事实却是"传统"编程方法(在*.h文件声明,在*.cpp文