程序设计2

 

程序设计1的问题,简单叙述其需求如下:

需要一种结构,要满足

(1)       其访问速度需要与数组基本一致,可随机存取。

(2)       无法预先知道其精确的存储空间,不应该先行扫描文本串来获得这个值,以避免时间效率的损失。

(3)       在申请存储空间失败的时候,可以进行有效的反应,不应使程序失控。

后来跟踪那个问题,发现文本数据中因为是专业技术文档的缘故,有大量的格式标注符号,其中的词汇信息若按不重复计应该是不超出百万级别的(中文词汇的个数有个基本的上限)。所以简单写了个模板类,实现:预先设定空间时并不申请所有空间、而在实际存取过程中动态分配空间,并且可以基本满足上述三个目标 这些特征。代码如下:

 

 

#ifndef __SIMPLEARRAY_H__

#define __SIMPLEARRAY_H__

 

/*

* 数组的模板类

* 数组的对象有两种类型,一是可c指针输出的(称为C格式Array),另一个是有着自己内存管理

* 方式的数组。后者的管理方式是,对于超过MAX_BLOCK_SIZE的数据,以块的方式进行组织。块的

* 最大个数为MAX_BLOCK_NUM。如此对于一定规模内(MAX_BLOCK_NUM*MAX_BLOCK_SIZE)的数据

* 既可以按照数组的随机存取方式访问数据,又可以根据实际需要自动申请空间,且不存在存储

* 数据移动的现象(如在动态数组中);代价是最多浪费近一个块的空间。

* 在实例化对象时需要指定类型(默认类型为非c格式数组),且类型不可改变。

****************************************************************************************/

#define       MAX_BLOCK_NUM      100

#define       MAX_BLOCK_SIZE         10000

 

template<typename T>

class CSimpleArray

{

public:

     CSimpleArray(bool bCArray = false);

     ~CSimpleArray(void);

 

     // 设置存储空间大小

     bool SetSize(int Size);

     // 获得存储空间大小

     int      GetSize(void);

     // 获得某位置的值引用

     T&       GetValue(int At);

     // 转换成c形式的数组(指针表示)

     T*       TO_C_ARRAY(void);

     // 释放资源

     void Clear(void);

 

private:

     void SetBlockNum(void);

 

private:

     T*       pValue;

     T**      pBlockValue;

     int      size;

     int      blockNum;

     int      curBlockNum;

 

     bool bAsCArray;

};

 

template<typename T>

CSimpleArray<T>::CSimpleArray(bool bCArray/* = false*/)

{

     pValue = NULL;

     pBlockValue = NULL;

     size = 0;

     blockNum = 0;

     curBlockNum = 0;

 

     bAsCArray = bCArray;

}

 

template<typename T>

CSimpleArray<T>::~CSimpleArray(void)

{

     Clear();

}

 

template<typename T>

void CSimpleArray<T>::SetBlockNum(void)

{

     blockNum = size/MAX_BLOCK_SIZE + 1;

     if( blockNum > MAX_BLOCK_NUM )

         blockNum = MAX_BLOCK_NUM;

}

 

template<typename T>

bool CSimpleArray<T>::SetSize(int Size)

{

     if( Size <= 0 || this->size == Size )

     {

         curBlockNum = 0;

         return true;

     }

 

     Clear();

     this->size = Size;

     if( Size > MAX_BLOCK_SIZE && !bAsCArray )

     {

         SetBlockNum();

         curBlockNum = 0;

         if( NULL == (pBlockValue = new T*[MAX_BLOCK_NUM]) )

              return false;

         for( int i = 0; i < MAX_BLOCK_NUM; i ++ )

              pBlockValue[i] = NULL;

     }

     else

     {

         if( NULL == (pValue = new T[size]) )

             return false;

     }

 

     return true;

}

 

template<typename T>

int CSimpleArray<T>::GetSize(void)

{

     return size;

}

 

template<typename T>

T& CSimpleArray<T>::GetValue(int At)

{

     if( At < 0 || At >= size )

         throw "GetElemException of wrong pos in CSimpleArray";

 

     if( pValue || bAsCArray )

         return pValue[At];

     else //if( pBlockValue )

     {

         int blockPos = At/MAX_BLOCK_SIZE;

         int valPos = At%MAX_BLOCK_SIZE;

         if( blockPos >= blockNum )

              throw "GetElemException of wrong pos in CSimpleArray";

         // 取到没有值的块则对该位置申请空间

         if( blockPos >= curBlockNum )

          {

              for( int i = curBlockNum; i <= blockPos; i ++ )

                   if( !pBlockValue[i] )

                       if( NULL == (pBlockValue[i] = new T[MAX_BLOCK_SIZE]) )

                            throw "New Block Failed in CSimpleArray";

              curBlockNum = blockPos + 1;

         }

        

         return (pBlockValue[blockPos])[valPos];

     }

}

 

template<typename T>

void CSimpleArray<T>::Clear(void)

{

     if( pValue )

     {

         delete[] pValue;

         pValue = NULL;

         size = 0;

     }

     if( pBlockValue )

     {

         for( int i = 0; i < curBlockNum; i ++ )

         {

              delete[] pBlockValue[i];

              pBlockValue[i] = NULL;

         }

         delete[] pBlockValue;

         pBlockValue = NULL;

         blockNum = 0;

         curBlockNum = 0;

         size = 0;

     }

}

 

template<typename T>

T* CSimpleArray<T>::TO_C_ARRAY(void)

{

     return pValue;

}

 

 

#endif //__SIMPLEARRAY_H__

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值