Srilm 阅读文档7

取自 自然语言处理百科

跳转到: 导航, 搜索

XCount.h XCount.cc

文档作者:jianzhu

创立时间:08.09.08


1、基本类


这两个文件定义了一个用于保存和管理次数(频数)的数据结构,该文件定义的XCount类用于保存频数,当该频数的值小或等于unsigned short(or unsigned),则将其保存直接保存到成员变量count中,并将成员变量indirect设为false。如果该频数的值大于unsigned short(or unsigned),则通过调用成员函数getXCountTableIndex来获得xcountTable中保存频数值的下标位置,将该位置保存到成语变量count中,而将频数保存到xcountTable[count]单元中,同时将成员变量indirect设为true。

XCount类

  该类提供如下函数
  a) 构造函数
  b) 析构函数
  c) 拷贝构造函数
  d) 重载的赋值运算符
  e) 重载的+=运算符
  f) 重载的-=运算符
  g) cast运算符

2、函数功能解释


a) 构造函数

<src>
0  XCount::XCount(XCountValue value)
1           : indirect(false)
2  {
3      if (value <= XCount_Maxinline) {
4        indirect = false;
5      count = value;
6      } else {
7      indirect = true;
8      count = getXCountTableIndex();
9
10     xcountTable[count] = value;
11    }
12 }
</src>
   功能:带参数的构造函数,用于将value值保存到创建的对象中。
   
   细解:第1行通过成员初始化列表的方式将indirect初始化为false;
   第3-6行判断当前要保存的value值是否超过XCountIndex的表示范围,
   若没有超过则将indirect设为false,同时将value值保存到count中;
   第6-11行用于处理当value值超过XCountIndex表示范围的情况,这时
   将indirect设为true,同时通过调用getXCountTableIndex函数获取
   保存当前value值的xcountTable数组下标位置,将count值设为
   该下标,并将value保存到xcountTable中的对应单元处。
   getXCountTableIndex函数
   <src>
  0   XCountIndex
 1  XCount::getXCountTableIndex()
 2  {
   3    static Boolean initialized = false;
 4
   5    if (!initialized) {
   6      // populate xcountTable free list
 7      for (XCountIndex i = 0; i < XCount_TableSize; i++) {
  8         xcountTable[i] = freeList;
  9         freeList = i;
 10     }
 11
   12     initialized = true;
   13   }
 14
   15   Boolean xcountTableEmpty = (freeList == XCount_Maxinline);
   16   assert(!xcountTableEmpty);
 17
   18   XCountIndex result = freeList;
   19   freeList = xcountTable[freeList];
 20
   21   refCounts[result] = 1;
   22   return result;
 23 }
   </src>
   功能:用于获取当前xcountTable中可用的单元对应的下标,同时将refCounts对应单元初始化
   为1,表示引用次数为1。同时返回可用单元对应的下标。
   
   细解:
   第3-13行用于判断是否初始化了xcountTable,如未初始化,则对其进行初始化操作,以链表
   方式初始化,其中下标对应于链表的指针。freeList指向链表单元的最后一个单元,xcountTable[
   freeList]中保存的值为下一个可用单元的索引;
   第15-16行用于判断当前xcountTable是否已经填满,即没有可用单元;
   第18行将freeList值保存到result中,即当前可用的数组单元;
   第19行将freeList置为下一个可用的单元索引位置;
   第21行将对应单元被应用次数设为1;
   第22行返回可用的数组单元索引。

b) 析构函数

<src>
0  XCount::~XCount()
1  {
2      if (indirect) {
3      freeXCountTableIndex(count);
4      }
5  }
</src>
   功能:用于析构当前的XCount类
  
   细解:
   第2-4行判断indirect是否为true,若为true,则当前XCount中的值保存在xcountTable中,而count
   中保存的只是其对应的索引,同时refCount中记录了其对应值被引用的次数;
   因此第3行调用freeXCountTableIndex函数进行相应的资源回收操作。
   freeXCountTableIndex函数
   <src>
   0  void
 1  XCount::freeXCountTableIndex(XCountIndex idx)
 2  {
   3    refCounts[idx] --;
   4    if (refCounts[idx] == 0) {
 5      xcountTable[idx] = freeList;
 6      freeList = idx;
   7    }
 8  }
   </src>
 功能:用于将idx对应的refCounts和xcountTable资源回收
 
 细解:第3行将refCounts对应的单元被引用计数减一;
 第4-7行处理refCounts引用计数为0后,xcountTable对应的资
 源回收操作。当refCounts对应单元的引用计数为0时,则需要
 将当前单元添加到可用单元中。首先通过第5行,将对应单元链
 接到可用单元列表中,然后通过第6行,将第一个可用单元置为
 当前刚被回收的单元。
 

c) 拷贝构造函数

<src>
0  XCount::XCount(const XCount &other)
1  {
2      indirect = other.indirect;
3      count = other.count;
4      if (indirect) {
5      refCounts[count] ++;
6      }
7  }
</src>
 功能:用于将当前创建的对象初始化为other
 
  细解:第2-3行初始化indirect和count两个成员变量
  第4-6行处理当indirect为true时,将refCounts[count]
  值增1,用于表示对应的xcountTable[count]单元中的值
  被一个新创建的对象所共享。

d) 重载的赋值运算符

<src>
0  XCount &
1  XCount::operator= (const XCount &other)
2  {
3      if (&other != this) {
4        if (indirect) {
5          freeXCountTableIndex(count);
6      }
7  
8      count = other.count;
9      indirect = other.indirect;
10
11     if (other.indirect) {
12         refCounts[other.count] ++;
13     }
14     }
15    return *this;
16 }
</src>
   功能:用于将当前other对象赋给当前对象
  
   细解:第3行判断是否存在自我赋值的情况,若是自我赋值,则直接
   运行第15行返回当前对象;否则判断当前对象的indirect是否为true,
   若为true,则调用freeXCountTableIndex函数对当前对象进行资源回收。
   第8-9行将count和indirect值初始化为other对应的值;第11-13行判断
   other.indirect是否为true,若为true则将refCounts对应的单元增1。

e) 重载的+=运算符

<src>
0  XCount & operator+= (XCountValue value)
1  {
2    *this = (XCountValue)*this + value;
3    return *this;
4  }
</src>
   功能:将XCount对象中保存的值加上value值
  
   细解:第2行首先通过调用cast函数(XCountValue),获取当前
   对象对应的value值,然后将其与value值相加,并通过调用
   构造函数构造将相加结果保存的构造出的对象中,然后通过
   调用赋值运算符,将当前对象初始化为构造出的对象;
   第3行返回运算后的当前对象,同时在退出当前函数作用域后对
   构造处的临时对象进行析构操作;
<src>
0  XCount & operator+= (XCount &value)
1  {
2    *this = (XCountValue)*this + (XCountValue)value;
3    return *this;
4  }
</src>
   该函数和上一个重载的+=运算符函数大同小异,只是调用了两次
   cast运算符,其余一样。
  

f) 重载的-=运算符

<src>
0  XCount & operator-= (XCountValue value)
1  {
2    *this = (XCountValue)*this - value;
3    return *this;
4  }
</src>
   该函数和上一个重载的+=运算符函数大同小异。
  
<src>
0   XCount & operator-= (XCount &value)
1  {
2    *this = (XCountValue)*this - (XCountValue)value;
3    return *this;
4  }
</src>
   该函数和上一个重载的+=运算符函数大同小异。
  

g) cast运算符

<src>
0  XCount::operator XCountValue() const
1  {
2      if (!indirect) {
3      return count;
4      } else {
5      return xcountTable[count];
6      }
7  }
</src>
   功能:用于返回当前对象中保存的value值
  
   细解:第2-4行处理当indirect为false的情况,即count中保存的
   即为频率值,而非索引。
   第4-6行处理indirect为true的情况,即count中保存的是索引,则
   返回xcountTable[count]的值。
 

知识点:


1、链表的数组表示

      一般情况下链表可以用指针的方式来实现,但通过数组下标的方式
  也可以实现链表的结构,如该类通过将xcountTable和freeList结合实现
  了一个简单的链表。

2、对象赋值

      *this = (XCountValue)*this + (XCountValue)value;
  上述语句中由于XCount类未提供类似于XCount & operator=
  (XCountValue Value);这样的重载赋值运算符,因此执行以下操作时:
      *this = value;
  发生以下操作过程
      XCount(XCountValue value = 0);            // 构建临时对象
      XCount & operator= (const XCount &other); // 调用赋值操作符函数
      ~XCount();                                // 析构临时对象


转自:http://blog.chinaunix.net/u1/58264/showart_1333609.html

个人工具
工具箱