隔了一段时间,忙其他的去了,下面继续偶之前的分词软件。

  在之前的3个版本里,我们已经实现了分词的基本功能,并对其合理性等作了大量的测试评估工作,但是性能的提升还很不如意,所以这里我提出了使用SortedList提高分词效率的方案。

  C#中提供了众多集合类的数据结构,如大家常用的List<T>,Dictionary<T>等,这里我将着重介绍一下SortedList,并实现其在偶的分词软件中的应用。

  

一、SortedList简介

引自MSDN:
  SortedList 元素可通过其键来访问 (如任意 IDictionary 实现中的元素),或通过其索引来访问(如任意 IList 实现中的元素)。

  SortedList 在内部维护两个数组以存储列表中的元素;即,一个数组用于键,另一个数组用于相关联的值。每个元素都是一个可作为 DictionaryEntry 对象进行访问的键/值对,
键不能为空引用(在 Visual Basic 中为 Nothing),但值可以。 
  SortedList 的容量是 SortedList 可以保存的元素数。SortedList 的默认初始容量为 0。随着元素添加到 SortedList 中,在需要时可以通过重新分配自动增加容量。可通过调用 
TrimToSize 或通过显式设置 Capacity 属性减少容量。

  SortedList 的元素将按照特定的 IComparer 实现(在创建 SortedList 时指定)或按照键本身提供的 IComparable 实现并依据键来进行排序。不论在哪种情况下,
SortedList 都不允许重复键。 索引顺序基于排序顺序。当添加元素时,元素将按正确的排序顺序插入 SortedList,同时索引会相应地进行调整。当移除元素时,索引也会相应地进行调整
。因此,当在SortedList 中添加或移除元素时,特定键/值对的索引可能会更改。 
  由于要进行排序,所以在 SortedList 上操作比在 Hashtable 上操作要慢。但是,SortedList 允许通过相关联键或通过索引对值进行访问,可提供更大的灵活性。 
  可使用一个整数索引访问此集合中的元素。此集合中的索引从零开始。 C# 语言中的 foreach 语句(在 Visual Basic 中为 for each)需要集合中每个元素的类型。
  由于 SortedList 的每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型。而是 DictionaryEntry 类型。

   

二、SortedList介绍——个人整理

    我们知道对于List<T>等集合,在查找某个元素是否存在时使用的是顺序遍历查找法,这样查询的偶然性比较大,效率低,而SortedList则采用了二分查找法,显著提高了查找效率(二分查找的介绍就略了吧)。

  SortedList保存数据时和哈希表一样用Key-Value的方式进行存储,但不同的是,它把Key和Value分别保存在两个object[]数组中,每次插入删除操作都会保持这两个object[]大小的同步性。

  SortedList在初始化时如果不指定大小,则会给一个默认的十六进制值0x10(16),在添加操作中,如果容量不足则会自动扩充为2倍容量,这些与ArrayList和Hashtable相同。

  SortedList的独特之处在于它保证数据的有序性,这点是如何保证呢?

  原来,在Add(key,value)方法中,SortedList会首先用二分查找插入的key值,如果有重复项,则报错,如果没有重复项,则根据key值大小,比较得出在集合中的位置,然后插入到该位置中,反编译查看源代码如下:

1 public void Add(TKey key, TValue value)
2 {
3  if (key == null)
4 {
5 System.ThrowHelper.ThrowArgumentNullException(System.Exceptio
6 nArgument.key);
7 }
   //二分查找
8 int num = Array.BinarySearch<TKey>(this.keys, 0, this._size, key, this.comparer);
9  if (num >= 0)
10 {
11 System.ThrowHelper.ThrowArgumentException(System.ExceptionResource.Argument_AddingDuplicate);
12 }
13 this.Insert(~num, key, value);
14 }
15
16  private void Insert(int index, TKey key, TValue value)
17 {
18  if (this._size == this.keys.Length)
19 {
20 this.EnsureCapacity(this._size + 1);
21 }
22 if (index < this._size)
23 {
24 Array.Copy(this.keys, index, this.keys, index + 1, this._size - index);
25 Array.Copy(this.values, index, this.values, index + 1, this._size - index);
26 }
27 this.keys[index] = key;
28 this.values[index] = value;
29 this._size++;
30 this.version++;
31 }

相关文章: