TStringList 与 泛型字典TDictionary 的 哈希功能效率PK

结论:做HashMap 映射 功能的时候 ,字典TDictionary 功能更强大,且效率更高,比如不仅仅可以存String,还可以存结构和类。

unit Unit5;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;

type
  TForm5 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  /// <summary>
  ///  第一种方法:
  ///  班级类,班级里有多个人,这里类里内置好每个人的英文名字和中文名字的映射
  ///  通过英文名字可以找到中文,通过中文名字也可以找到英文
  /// </summary>
  TBanJi111 = class
    const
      /// <summary>
      /// 这叫类常量,可以把人名 英文---->中文 定义在这里
      /// </summary>
      studentNameEnToCnListStr = ‘XiaoLi=李飞刀,XiaoWang=王中王,XiaoZhang=张飞‘;
    public
      /// <summary>
      ///  通过英文获取中文的方法
      /// </summary>
      function getNameCnByEn(const nameEn: string): string;

      /// <summary>
      /// 通过中文获取应该的方法
      /// </summary>
      function getNameEnByCn(const nameCn: string): string;
  end;

  /// <summary>
  ///  第二种方法:
  ///  用2个TStringList属性,
  ///  key,value做下置换
  /// </summary>
  TBanJi222 = class
  private
    FNameEnToCnList: TStringList;
    FNameCnToEnList: TStringList;
    procedure SetNameCnToEnList(const Value: TStringList);
    procedure SetNameEnToCnList(const Value: TStringList);
  public
    constructor Create;
    destructor Destroy; override;
    property NameCnToEnList: TStringList read FNameCnToEnList write SetNameCnToEnList;
    property NameEnToCnList: TStringList read FNameEnToCnList write SetNameEnToCnList;
  end;

  /// <summary>
  /// 第三种方法
  /// 用泛型
  /// </summary>
  TBanJi333 = class
  private
    FNameEnToCnMap: TDictionary<string, string>;
    FNameCnToEnMap: TDictionary<string, string>;
    procedure SetNameCnToEnMap(const Value: TDictionary<string, string>);
    procedure SetNameEnToCnMap(const Value: TDictionary<string, string>);
  public
    constructor Create;
    destructor Destroy; override;
    property NameCnToEnMap: TDictionary<string, string> read FNameCnToEnMap write SetNameCnToEnMap;
    property NameEnToCnMap: TDictionary<string, string> read FNameEnToCnMap write SetNameEnToCnMap;
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var
  bb: TBanJi111;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi111.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.getNameCnByEn(‘XiaoLi‘));
    Memo1.Lines.Add(bb.getNameEnByCn(‘李飞刀‘));

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.getNameCnByEn(‘XiaoLi‘);
      //通过中文取英文
      response2 := bb.getNameEnByCn(‘李飞刀‘);
    end;
    Memo1.Lines.Add(‘总耗时(毫秒): ‘ + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

{ TBanJi }

function TBanJi111.getNameCnByEn(const nameEn: string): string;
var
  MyList: TStringList;
begin
  MyList := TStringList.Create;
  try
    MyList.CommaText := studentNameEnToCnListStr;
    Result := MyList.Values[nameEn];
  finally
    MyList.Free;
  end;
end;

function TBanJi111.getNameEnByCn(const nameCn: string): string;
var
  MyList: TStringList;
  I: Integer;
begin
  MyList := TStringList.Create;
  try
    MyList.CommaText := studentNameEnToCnListStr;
    for I := 0 to (MyList.Count - 1) do
    begin
      if nameCn = MyList.ValueFromIndex[I] then
      begin
        Result := MyList.Names[I];
        Break;
      end;
    end;
  finally
    MyList.Free;
  end;
end;

{ TBanJi2 }

constructor TBanJi222.Create;
var
  I: Integer;
begin
  inherited Create;
  Self.FNameEnToCnList := TStringList.Create;
  Self.FNameCnToEnList := TStringList.Create;
  //把项目逐条加载进来
  Self.FNameEnToCnList.Add(‘XiaoLi=李飞刀‘);
  Self.FNameEnToCnList.Add(‘XiaoWang=王中王‘);
  Self.FNameEnToCnList.Add(‘XiaoZhang=张飞‘);
  //key与value反转写入另一个TStringList
  for I := 0 to Self.FNameEnToCnList.Count - 1 do
  begin
   Self.FNameCnToEnList.Add(Self.FNameEnToCnList.ValueFromIndex[I] + ‘=‘ + Self.FNameEnToCnList.Names[I]);
  end;
end;

destructor TBanJi222.Destroy;
begin
  Self.FNameEnToCnList.Free;
  Self.FNameCnToEnList.Free;
  inherited Destroy;
end;

procedure TBanJi222.SetNameCnToEnList(const Value: TStringList);
begin
  FNameCnToEnList := Value;
end;

procedure TBanJi222.SetNameEnToCnList(const Value: TStringList);
begin
  FNameEnToCnList := Value;
end;

procedure TForm5.Button2Click(Sender: TObject);
var
  bb: TBanJi222;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi222.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.NameEnToCnList.Values[‘XiaoLi‘]);
    Memo1.Lines.Add(bb.NameCnToEnList.Values[‘李飞刀‘]);

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.NameEnToCnList.Values[‘XiaoLi‘];
      //通过中文取英文
      response2 := bb.NameCnToEnList.Values[‘李飞刀‘];
    end;
    Memo1.Lines.Add(‘总耗时(毫秒): ‘ + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

procedure TForm5.Button3Click(Sender: TObject);
var
  bb: TBanJi333;
  I: Integer;
  start_miao: Int64;
  response1, response2: string;
begin
  bb := TBanJi333.Create;
  try
    //看下结果
    Memo1.Lines.Clear;
    Memo1.Lines.Add(bb.NameEnToCnMap[‘XiaoLi‘]);
    Memo1.Lines.Add(bb.NameCnToEnMap[‘李飞刀‘]);

    //循环测试性能
    start_miao := GetTickCount;
    for I := 0 to 100000 do
    begin
      //通过英文取中文
      response1 := bb.NameEnToCnMap[‘XiaoLi‘];
      //通过中文取英文
      response2 := bb.NameCnToEnMap[‘李飞刀‘];
    end;
    Memo1.Lines.Add(‘总耗时(毫秒): ‘ + (GetTickCount - start_miao).ToString);
  finally
    bb.Free;
  end;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

{ TBanJi333 }

constructor TBanJi333.Create;
var
  myKey: string;
begin
  inherited Create;
  Self.FNameEnToCnMap := TDictionary<string, string>.Create();
  Self.FNameCnToEnMap := TDictionary<string, string>.Create();

  //把项目逐条加载进来
  Self.FNameEnToCnMap.Add(‘XiaoLi‘, ‘李飞刀‘);
  Self.FNameEnToCnMap.Add(‘XiaoWang‘, ‘王中王‘);
  Self.FNameEnToCnMap.Add(‘XiaoZhang‘, ‘张飞‘);

  //key与value反转写入另一个TDictionary
  for myKey in Self.FNameEnToCnMap.Keys do
  begin
   Self.FNameCnToEnMap.Add(Self.FNameEnToCnMap[myKey], myKey);
  end;
end;

destructor TBanJi333.Destroy;
begin
  Self.FNameEnToCnMap.Free;
  Self.FNameCnToEnMap.Free;
  inherited Destroy;
end;

procedure TBanJi333.SetNameCnToEnMap(const Value: TDictionary<string, string>);
begin
  FNameCnToEnMap := Value;
end;

procedure TBanJi333.SetNameEnToCnMap(const Value: TDictionary<string, string>);
begin
  FNameEnToCnMap := Value;
end;

end.
时间: 2024-10-09 19:59:17

TStringList 与 泛型字典TDictionary 的 哈希功能效率PK的相关文章

Python算法教程第二章知识点:计时模块、字典与散哈希表、图与树的实现、成员查询、插入对象

本文目录:一.计时模块:二.字典与散哈希表:三.图与树的实现:四.成员查询:五.插入对象</br>一.计时模块(timeit.cProfile) import timeit timeit.timeit('x = 1 + 2') 既然学习算法,那么来计算程序所耗费的时间是重要的,但是需要注意:timeit()计时函数会多次运行相关的代码段并求得平均值,以提高计时的精准度,所以,我们需要预防早先的执行操作影响之后代码的执行.举个栗子:若我们执行排序算法,则只有第一次执行代码时是在随机的情况下计时,

泛型字典类比较

[转] Dictionary<TKey,TValue>, SortedDictionary<TKey,TValue>, SortedList<TKey,TValue>横向评测 Dictionary<TKey,TValue>.SortedDictionary<TKey,TValue>与 SortedList<TKey,TValue>是.NET Framework的三个泛型的关键字查找的类,都属于System.Collections.Ge

泛型字典

// 声明 bplList: TDictionary<string, Integer>; // 创建 bplList := TDictionary<string, Integer>.Create; // 往字典里增加一条 h := LoadPackage(bplName); bplList.Add(bplName, h); // 查字典 if not bplList.ContainsKey(bplName) then // 遍历字典 var i: Integer;...... fo

Combobox绑定泛型字典时提示&ldquo;复杂的 DataBinding 接受 IList 或 IListSource 作为数据源&rdquo;的解决方法

一般情况下我们会将 DataTable 或 DataView 绑定到 Combobox 控件上,这时候进行数据绑定是没有问题的,因为DataTable 和 DataView 都继承了 IList 接口.但是有些情况下我们需要将泛型的集合类当作数据源,这时候就会报 复杂的 DataBinding 接受 IList 或 IListSource 作为数据源 的错误.原因是这些类型没有继承上述的两个接口,所以要使用一个 BindingSource 类将数据源封装一下,BindingSource 类继承和

哈希表效率2

开放地址法的装填因子: loadFactor = nItems/arraySize; 有10000个单元的哈希表填入6667个数据后. 它的装填因子2/3 链地址法的装填因子:一般比一1大. 如果链表中有许多项.存取时间就会变长. 因为存取特定数据向平均需要搜索链表的一半数据项. 找到初始的单元需要O[1]的时间级别. 搜索链表时间与M<链表包含的平均数据项>为正比.O[M]

哈希表效率

开放地址法的装填因子: loadFactor = nItems/arraySize; 有10000个单元的哈希表填入6667个数据后. 它的装填因子2/3 链地址法的装填因子:一般比一1大. 如果链表中有许多项.存取时间就会变长. 因为存取特定数据向平均需要搜索链表的一半数据项. 找到初始的单元需要O[1]的时间级别. 搜索链表时间与M<链表包含的平均数据项>为正比.O[M] 哈希表的效率: <无冲突发生> 插入 O[1] 查找 O [1] <发生冲突>

C# - ArrayList与Hashtable及其泛型版本

C#的集合类继承关系UML图: ICollection - ICollection<T> ICollection:所有非泛型集合的大小.枚举器和同步方法 public interface ICollection : IEnumerable { int Count { get; } bool IsSynchronized { get; } // 对ICollection的访问是否是同步的(线程安全) object SyncRoot { get; } // 获取可用于对ICollection同步访

c# 图解泛型List&lt;T&gt;, HashTable和Dictionary&lt;TKey,TValue&gt;

前辈在代码中使用了HashTable,由于我用的比较少,不能理解,为什么不用Dictionary?看了源码以及查阅资料,总结如下: 首先看看它们的继承体系: 我把list<T>的继承体系也一并画出来,因为c#集合中List<T>和Dictionary<T>这两种数据结构实在太常用了.从上图中可以看到Dictionary和HashTable都继承于IDictionary.既然父辈都相同,那么注定会有很多相似的地方.那么它们又会有哪些不同呢? 这个还得研究源码,先看看Has

一起学 Java集合框架、数据结构、泛型

一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个层次. 实现(类):是集合接口的具体实现.从本质上讲,它们是可重复使用的数据结构. 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序.这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现. 集合接口 序号 name 接口描述 1 Collection Col