一目了然<br><br>unit untDict;<br><br>interface<br>uses SysUtils,StrUtils, Variants, Classes,Dialogs;<br><br>const Words='words.txt'; //字典文件名<br><br><br>//链表元素<br>type<br>PChainElem=^ChainElem;<br>ChainElem=record<br> value
ointer; //指向一个TCharTreeNode<br> sucElem
ChainElem; //后继节点指针(即:子树根节点及其兄弟节点)<br>end;<br>//链表类<br>type TChain=class<br> private<br> head,tail
ChainElem;<br> published<br> constructor create;<br> destructor destroy;override;<br> procedure ApendElem(curElem
ChainElem); //在链表尾追加一个节点<br> function GetNext(curElem
ChainElem)
ChainElem; //返回当前节点的下一个节点(兄弟)<br> { property ChainHead
ointer read GetHead write SetChainHead default nil; //头节点为空,说明是叶子了。(父节点)}<br> function GetHead
ChainElem; //获得表头节点<br><br>end;<br><br>//树节点<br>type TCharTreeNode=class{(TChain)}<br> private<br> sValue:Word;//保存汉字的索引,通过该值可以计算出汉字的机内码,从而还原成汉字<br> WordEnd:Boolean; //成词标记<br> WordFreq:Word; //词频<br> Chain:TChain; //儿子节点组成的链表<br> ParentNode:TCharTreeNode; //父节点指针<br> function GetCharacter:string;<br> procedure SetCharacter(s:String);<br> procedure SetWordEnd(V:boolean);<br> procedure SetWordFreq(AFreq:Word);<br> published<br> constructor create;<br> destructor destroy;override;<br> function AddChild(const character:string;wFreq:longint=0;Wordend:Boolean=false):TCharTreeNode; //<br> function GetFirstChild:TCharTreeNode; //第一个孩子节点<br> function GetFirstElem
ChainElem;<br> function GetNextSibling(Elem
ChainElem):TCharTreeNode; //获得兄弟节点指针}<br> function GetNextElem(Elem
ChainElem)
ChainElem;<br><br> property Character:string read GetCharacter write SetCharacter ;<br> property IsWordEnd:Boolean read wordEnd write SetWordEnd default false;<br> property WordFreqs:Word read WordFreq write SetWordFreq default 1;<br> <br> function GetParent:TCharTreeNode; //获得父节点指针<br> function GetHead
ChainElem;<br>end;<br><br>//树<br>type TCharTree=class<br> private<br> root:array[Word] of TCharTreeNode;<br> NodeCount:LongWord; //节点个数<br> procedure setCount(V:LongWord);<br> procedure FreeAllNode(Node:TCharTreeNode);<br> public<br> constructor create;<br> destructor destroy;override;<br> published<br> property Count:LongWord read NodeCount write SetCount;<br> function GetRoot(i:Word):TCharTreeNode;<br>end;<br><br>//数据库的数据载入到树---字典类<br>type TDictType=(dtOrder,dtReveser);<br><br>type PFreqAndWord=^TFreqAndWord;<br> TFreqAndWord=record<br> iFreq,<br> iLen:Integer;<br> end;<br><br><br>type TArrayString=array[0..249]of TFreqAndWord;<br> TArrayBool=array[0..249]of Boolean;<br><br> PArrayString=^TArrayString;<br> PArrayBool=^TArrayBool;<br><br>type TInterfacedDict=class(TInterfacedobject)<br> private<br> FTree:TCharTree;<br> FDictType:TDictType;<br> FDictPath:string;<br><br> function NodesCount:LongWord;<br> procedure SetNodeCount(ACount:LongWord);<br> protected<br> procedure SetDictType(AType:TDictType);<br> procedure SetDictPath(Apath:string);<br><br> public<br> class function ChangeDict(APath:string):TInterfacedDict;virtual; //切换字典<br> class function PlusDict(APath:string):TInterfacedDict;virtual;<br><br> function FindCharacter(S:AnsiString;nd:TCharTreeNode=nil):TCharTreeNode;//若nd=nil,则是查找根节点。否则,在nd的儿子里查找<br> //function FindWordInDict(S: string): TCharTreeNode;virtual; //S是否是一个词<br> function Trace(node1:TCharTreeNode):string;virtual; //没有匹配到,则须向上回溯<br> function TraceAll(node1:TCharTreeNode;var FItem:TArrayString):Integer;virtual; //没有匹配到,则须向上回溯(找出路径上所有可以成词的词)<br> function GetRoot(i:word):TCharTreeNode;overload;<br> function GetRoot(c:AnsiString):TCharTreeNode;overload;<br> function GetFreq(var nd:TCharTreeNode):word;virtual;<br> function GetFee(nd:TCharTreeNode):word;virtual;<br><br> constructor create;<br> destructor Destroy;override;<br><br> procedure LoadDict(APath: string);virtual; //载入不同的字典--->由子类去实现。<br><br> property Tree:TCharTree read FTree write FTree;<br> property Count:LongWord read NodesCount write SetNodeCount;<br> property DictType:TDictType read FDictType {write SetDictType}; //只读<br> property DictPath:string read FDictPath write SetDictPath;<br> procedure AfterConstruction; override;<br>end;<br>type TDict=class(TInterfacedDict) //单例类<br> private<br> <br> published<br> procedure LoadDict(APath: string);override;<br><br> public<br> class function GetInstance(chooce:Integer):TDict;<br> constructor Create(APath: string);<br> class function CreateInstance(APath:string):Tdict; //创建单例类<br> class function ChangeDict(APath:string):TInterfacedDict;override;<br> class function PlusDict(APath:string):TInterfacedDict; override;<br> <br> procedure ReleaseInstance; //释放单例类<br> destructor Destroy;override;<br>end;<br>type TReverseDict=class(TInterfacedDict) //逆序载入字典,供逆向最大匹配使用<br> published<br> procedure LoadDict(APath: string);override;<br><br> public<br> class function GetInstance(chooce:Integer):TReverseDict;<br> constructor Create(APath: string);<br> class function CreateInstance(APath:string):TReverseDict; //创建单例类<br> class function ChangeDict(APath:string):TInterfacedDict;override;<br> class function PlusDict(APath:string):TInterfacedDict;override;<br> procedure ReleaseInstance; //释放单例类<br> destructor Destroy;override;<br>end;<br><br>var<br> DictInstance:TDict; {正序字典和逆序字典的实例}<br> RevDictInstance:TReverseDict;<br><br>implementation<br>uses untConst{,IniOp};<br>var <br> iDictRefCount,iRevDictRefCount:Integer; {字典的引用计数}<br> <br><br>{ TChain }<br><br>procedure TChain.ApendElem(curElem: PChainElem);<br>{var<br> curPointer
ChainElem;}<br>begin<br> if Self.head=nil then<br> begin<br> head:=curElem;<br> tail:=curElem;<br> Exit;<br> end;<br><br> tail.sucElem:=curElem;<br> tail:=curElem;<br>end;<br><br>constructor TChain.create;<br>begin<br> head:=nil;<br> tail:=nil;<br>end;<br><br>destructor TChain.destroy;<br>var<br> Pcur,Pnext
ChainElem;<br>begin<br> Pcur:=head;<br> while (Pcur<>nil) do<br> begin<br> pNext:=pCur^.sucElem;<br> if Pcur^.value<>nil then<br> begin<br> TCharTreeNode(Pcur^.value).Free;<br> Dispose(pCur);<br> end;<br> pCur:=pNext;<br> end;<br> inherited;<br>end;<br><br>function TChain.GetHead
ChainElem;<br>begin<br> Result:=head;<br>end;<br><br>function TChain.GetNext(curElem: PChainElem): PChainElem;<br>begin<br> Result:=curElem^.sucElem;<br>end;<br><br>{ TCharTreeNode }<br><br>function TCharTreeNode.AddChild(const character: string;wFreq:longint;Wordend:Boolean):TCharTreeNode;<br>var<br> tn:TCharTreeNode;<br> ChainItem
ChainElem;<br>begin<br> tn:=TCharTreeNode.create;<br> tn.sValue:=word(byte(character[1]) shl 8) + word(character[2]);<br> tn.WordEnd:=Wordend;<br> tn.WordFreq:=wFreq;<br> tn.ParentNode:=Self;<br><br> New(ChainItem);<br> ChainItem^.value:=pointer(tn); ///<br> ChainItem^.sucElem:=nil;<br><br> Self.Chain.ApendElem(ChainItem); //加入到儿子链表中<br> Result:=tn;<br>end;<br><br>constructor TCharTreeNode.create;<br>begin<br> Chain:=TChain.create;<br> ParentNode:=nil;<br>end;<br><br>destructor TCharTreeNode.destroy;<br>begin<br> Chain.destroy;<br> inherited;<br>end;<br><br>function TCharTreeNode.GetCharacter: string;<br>{var<br> //S:string;<br> preByte,sucByte:Byte;}<br>begin<br> SetLength(Result,2);<br> Result[1]:=Char(Byte((sValue and 65280) shr 8));<br> Result[2]:=Char(Byte(sValue and 255));<br>end;<br><br><br>function TCharTreeNode.GetFirstChild: TCharTreeNode; //获得第一个孩子节点<br>begin<br> if Assigned(Chain.GetHead.value) then<br> Result:= TCharTreeNode(Chain.GetHead.value)<br> else<br> Result:=nil;<br>end;<br><br>function TCharTreeNode.GetParent: TCharTreeNode;<br>begin<br> result:=Self.ParentNode;<br>end;<br><br>function TCharTreeNode.GetNextSibling(Elem
ChainElem): TCharTreeNode; //获得当前节点的兄弟<br>begin //参数为 当前节点所在的PChainElem<br> if Elem.sucElem<>nil then<br> result:= TCharTreeNode(Elem.sucElem.value)<br> else<br> Result:=nil;<br>end;<br><br>procedure TCharTreeNode.SetCharacter(s: String);<br>begin<br> sValue:=word(Byte(S[1]) shl 8) +word(Byte(s[2]));<br>end;<br><br>procedure TCharTreeNode.SetWordEnd(V: boolean);<br>begin<br> WordEnd:=V;<br>end;<br><br>function TCharTreeNode.GetNextElem(Elem: PChainElem): PChainElem;<br>begin<br> Result:=Elem.sucElem;<br>end;<br><br>function TCharTreeNode.GetFirstElem: PChainElem;<br>begin<br> Result:=Self.Chain.GetHead;<br>end;<br><br>function TCharTreeNode.GetHead: PChainElem;<br>begin<br>Result:=Chain.head;<br>end;<br><br>procedure TCharTreeNode.SetWordFreq(AFreq: Word);<br>begin<br> WordFreq:=AFreq;<br>end;<br><br>{ TCharTree }<br><br>constructor TCharTree.create;<br>var<br> I:Word;<br>begin<br><br> for i:=0 to 65535 do //根<br> begin<br> root
:=TCharTreeNode.create;<br> root.sValue:=i;<br> root.WordEnd:=False; //默认不是单字词 <br> end;<br> NodeCount:=65536;<br>end;<br><br>destructor TCharTree.destroy;<br>var<br> i:Word;<br>begin<br> //做树的遍历,释放每一个节点<br> for i:=0 to 65535 do<br> FreeAllNode(root);<br> inherited;<br>end;<br><br>procedure TCharTree.FreeAllNode(Node:TCharTreeNode);<br>var<br> Vointer;<br>begin<br> if Node=nil then Exit;<br> if (Node.Chain=nil) then<br> begin<br> Node.Free;<br> Exit;<br> end;<br> if (Node.GetHead=nil) then<br> begin<br> Node.Free;<br> Exit;<br> end;<br> if Node.GetHead.value<>nil then //如果它还有儿子节点,<br> begin<br> V:=Node.GetHead.value;<br> Node.Chain.head:=Node.GetHead.sucElem;<br> FreeAllNode(TCharTreeNode(V));<br> end<br> else<br> TCharTreeNode(V).Free;<br>end;<br><br>function TCharTree.GetRoot(i: Word): TCharTreeNode;<br>begin<br> Result:=root;<br>end;<br><br>procedure TCharTree.setCount(v:LongWord);<br>begin<br> NodeCount:=v;<br>end;<br><br><br><br>{ TDict }<br>class function TDict.ChangeDict(APath: string): TInterfacedDict;<br>begin<br> if Assigned(TDict.GetInstance(0)) then<br> begin<br> if TDict.GetInstance(0).DictPath=Trim(APath) then //字典相同<br> begin<br> Result:=TDict.GetInstance(0);<br> Exit;<br> end<br> else<br> TDict.GetInstance(0).ReleaseInstance; //字典不同,则释放以前字典,并重新加载新字典<br> end;<br> Result:=TDict.CreateInstance(APath);<br> try<br> Result.LoadDict(APath);<br> except<br> {$Message Hint 'show some error information abort Dict'}<br> Abort;<br> end;<br>end;<br><br>constructor TDict.Create(APath: string);<br>begin<br>// inherited Create;<br>// LoadDict(APath+words);<br> raise Exception.CreateFmt(StrCreateError,[ClassName]);<br>end;<br><br>class function TDict.CreateInstance(APath: string):TDict;<br>begin<br> <br> Result:=GetInstance(1);<br> //LoadDict(APath+words);<br>end;<br><br>destructor TDict.Destroy;<br>begin<br> if GetInstance(0)=Self then GetInstance(2);<br> inherited;<br>end;<br><br>class function TDict.GetInstance(chooce: Integer): TDict;<br>//const instance:TDict=nil;<br>begin<br> case chooce of<br> 0: ; //供释放使用<br> 1: //创建<br> begin<br> Inc(iDictRefCount,1);<br> if not Assigned(DictInstance) then<br> begin<br> DictInstance:=inherited Create;<br> //LoadDict(APath+words);<br> end ;<br> end;<br> 2: DictInstance:=nil; //赋值<br> else<br> raise Exception.CreateFmt(strCreateParamError,[ClassName]);<br> end;<br> <br> Result:=DictInstance;<br>end;<br><br>procedure TDict.LoadDict(APath: string);<br>var<br> nd,tmpNode:TCharTreeNode;<br> str:string;<br> index:Word;<br> i,j:LongWord;<br> {ItemChainElem; }<br> {isExsit:Boolean;}<br> F:TextFile;<br> PosDel1,PosDel2:Integer;<br> wfreq:string;<br><br> lst:TStringList;<br> sTip:string;<br> procedure Split(Splitor,Str:string); //sSubstr分割sStr,存入TStringList.<br> var<br> PSplitor,PStr,PPosAnsiChar;<br> s:string;<br> begin<br> PSplitor:=PAnsiChar(Splitor);<br> PStr:=PAnsiChar(Str);<br> PPos:=PAnsiChar(Str);<br><br> while PPos<>#0 do<br> begin<br> while (PPos^<>PSplitor^) and (PPos^<>#0) do inc(PPos);<br><br> SetString(S,PStr,PPos-PStr);<br> lst.Add(S);<br><br> if PPos^<>#0 then inc(PPos)<br> else break;<br><br> pstr:=ppos;<br> end;<br> end;<br><br>begin<br> SetDictType(dtOrder); //指定字典属性<br> FDictPath:=APath;<br><br> lst:=TStringList.Create;<br> try<br> AssignFile(F,Apath);<br> try<br> Reset(F);<br> except<br> MessageDlg((Format(StrFileNotFound,[APath])),mtWarning,[mbOK],0);<br> Abort;<br> end;<br> try<br> while (not Eof(F)) do //把每一个词加载到树上<br> begin<br> Readln(F,str); //在字典中取词<br> sTip:=str;<br> Split(#9,str); {格式如: 22072 "分段" 5}<br> str:=lst.Strings[1];<br> PosDel1:=Pos('"',str); {如果是汉字,则左右两侧有双引号,去掉双引号}<br> PosDel2:=LastDelimiter('"',str);<br> str:=Copy(str,PosDel1+1 ,PosDel2-PosDel1-1); //剔除双引号<br> if lst.Count>=3 then<br> wfreq:=lst.Strings[2];<br><br> lst.Clear;<br> if Length(str)<=1 then Continue; //不是汉字(应该不会出现)<br> try<br> index:=word(Byte(str[1]) shl 8)+ word(Byte(str[2])); //树根节点索引<br> except<br> MessageDlg(Format(StrRowError,[sTip]),mtWarning,[mbOK],0);<br> Halt;<br> end;<br> nd:=Tree.root[index];<br><br> if Length(str)=2 then //单字词<br> begin<br> nd.WordFreq:=nd.WordFreq+StrToInt(wFreq);<br> nd.WordEnd:=True;<br> continue ;<br> end;<br> for i:=1 to (Length(str) div 2)-1 do<br> begin<br> tmpNode:=FindCharacter(Copy(str,i*2+1,2),nd);<br> if tmpNode=nil then<br> nd:=nd.AddChild(Copy(str,i*2+1,2)) //值相等的节点不存在。追加。<br> else<br> begin<br> nd:=tmpNode;<br> Continue;<br> end;<br> Tree.Count:=tree.count+1; //树节点个数加1<br> end; //end 'for'<br><br> nd.WordFreq:=StrToIntdef(wfreq,1); //词频<br> nd.WordEnd:=True; //词结束标记<br> end;<br> except<br> MessageDlg(StrLoadDictError,mtInformation,[MBOK],0);<br> Abort;<br> end;<br> finally<br> lst.Free;<br> CloseFile(F);<br> end;<br>end;<br><br><br>class function TDict.PlusDict(APath: string): TInterfacedDict;<br>begin<br> { if Assigned(TDict.GetInstance(0)) then<br> begin<br> TDict(TDict.GetInstance(0))<br> end; }<br>end;<br><br>procedure TDict.ReleaseInstance;<br>begin<br> Dec(iDictRefCount,1);<br> if iDictRefCount>0 then Exit;<br> if GetInstance(0)<>nil then<br> GetInstance(0).Free;<br>end;<br><br><br><br><br><br>{ TInterfacedDict }<br><br>procedure TInterfacedDict.AfterConstruction;<br>begin<br> inherited;<br> //<br>end;<br><br>class function TInterfacedDict.ChangeDict(APath: string): TInterfacedDict;<br>begin<br> //空. 须被覆盖.本想使用Virtui+Abstract修饰,但抽象类不能创建实例.<br> //下同.<br>end;<br><br>constructor TInterfacedDict.Create;<br>begin<br> inherited;<br> FTree:=TCharTree.Create;<br>end;<br><br>destructor TInterfacedDict.Destroy;<br>begin<br> FreeAndNil(FTree);<br> inherited;<br>end;<br><br>function TInterfacedDict.FindCharacter(S: AnsiString;<br> nd: TCharTreeNode): TCharTreeNode;<br>var //查找nd的子节点中值为S的节点。若找到了,则返回该子节点,否则返回nil<br> ItemChainElem; //若nd 缺省,则返回值为S的根节点<br>begin<br> if nd=nil then //返回根节点<br> Result:=GetRoot(S)<br> //Result:=GetRoot(word(Byte(S[1]) shl 8) +word(byte(s[2])))<br> else<br> begin<br> item:=nd.GetHead;<br> while(item<>nil) do<br> begin<br> if (TCharTreeNode(item.value)).Character=s then //找到值相等的儿子节点<br> begin<br> Result:= TCharTreeNode(item.value);<br> Exit;<br> end<br> else<br> item:=item.sucElem;<br> end;<br> Result:=nil;<br> end;<br>end;<br><br><br><br><br>function TInterfacedDict.GetFee(nd: TCharTreeNode): word;<br>begin<br> //<br>end;<br><br>function TInterfacedDict.GetFreq(var nd: TCharTreeNode): word;<br>begin<br> Result:=nd.WordFreq;<br>end;<br><br>function TInterfacedDict.GetRoot(i:word):TCharTreeNode;<br>begin<br> Result:=Tree.GetRoot(i);<br>end;<br><br>function TInterfacedDict.GetRoot(c: AnsiString): TCharTreeNode;<br>var<br> wIndex:word;<br>begin<br> wIndex:=Word(byte(c[1]) shl 8) + Word(c[2]);<br> //if FTree=nil then ShowMessage('tree nil');<br> Result:=Tree.GetRoot(wIndex);<br>end;<br><br>procedure TInterfacedDict.LoadDict(APath: string);<br>begin<br> //<br>end;<br><br>function TInterfacedDict.NodesCount: LongWord;<br>begin<br> Result:=Tree.NodeCount;<br>end;<br><br>class function TInterfacedDict.PlusDict(APath: string): TInterfacedDict;<br>begin<br> //<br>end;<br><br>procedure TInterfacedDict.SetDictPath(Apath: string);<br>begin<br> FDictPath:=Apath;<br>end;<br><br>procedure TInterfacedDict.SetDictType(AType: TDictType);<br>begin<br> FDictType:=AType;<br>end;<br><br>procedure TInterfacedDict.SetNodeCount(ACount: LongWord);<br>begin<br> Tree.NodeCount:=ACount;<br>end;<br><br>function TInterfacedDict.Trace(node1: TCharTreeNode): string;<br>var<br> isStart:Boolean;<br> nd:TCharTreeNode;<br>begin<br> isStart:=False;<br> Result:='';<br> if node1=nil then raise Exception.Create('Trace错误!'); //如果node1=nil 可能出现死循环<br> repeat<br><br> if node1.IsWordEnd then isStart:=True;<br> if isStart then Result:=node1.Character+Result; //分词结果<br><br> nd:=node1.GetParent;<br> if nd=nil then Break; {回溯到了根节点}<br><br> node1:=nd;<br> until (false); //回溯<br>end;<br><br>function TInterfacedDict.TraceAll(node1: TCharTreeNode;var FItem:TArrayString):Integer;<br>var<br> nd:TCharTreeNode;<br> bItem:TArrayBool;<br> i,j:Integer;<br>begin<br> if node1=nil then raise Exception.CreateFmt(StrNotAssignedError,[node1.ClassName]); //如果node1=nil 可能出现死循环<br><br> FillChar(FItem,SizeOf(TArrayString),0);<br> i:=0;<br> repeat<br> if node1.IsWordEnd then<br> begin<br> bItem:=True;<br> FItem.iFreq:=node1.WordFreqs;<br> Inc(i);<br> end;<br><br> if i>10 then raise Exception.Create(StrOverBoundsError);<br> <br> for j:=0 to i-1 do<br> if bItem[j] then<br> FItem[j].iLen:=FItem[j].iLen+Length(node1.Character); //长度计数<br><br> nd:=node1.GetParent;<br> <br> if nd=nil then Break; {回溯到了根节点}<br><br> node1:=nd;<br> until (false); //回溯<br> result:=i; //左临词的个数<br>end;<br><br>{ TReverseDict }<br><br>class function TReverseDict.ChangeDict(APath: string): TInterfacedDict;<br>begin<br> if Assigned(TReverseDict.GetInstance(0)) then<br> begin<br> if TReverseDict.GetInstance(0).DictPath=Trim(APath) then //字典相同<br> begin<br> Result:=TReverseDict.GetInstance(0);<br> Exit;<br> end<br> else<br> TReverseDict.GetInstance(0).ReleaseInstance; //字典不同,则释放以前字典,并重新加载新字典<br> end;<br> Result:=TReverseDict.CreateInstance(APath);<br> Result.LoadDict(APath);<br>end;<br><br>constructor TReverseDict.Create(APath: string);<br>begin<br> raise Exception.CreateFmt(StrCreateError,[ClassName]);<br>end;<br><br>class function TReverseDict.CreateInstance(APath: string):TReverseDict;<br>begin<br> <br> Result:=GetInstance(1);<br> //LoadDict(APath+words);<br>end;<br><br>destructor TReverseDict.Destroy;<br>begin<br> if GetInstance(0)=Self then GetInstance(2);<br> inherited;<br>end;<br><br>class function TReverseDict.GetInstance(chooce: Integer): TReverseDict;<br>//const instance:TDict=nil;<br>begin<br> case chooce of<br> 0: ; //供释放使用<br> 1: //创建<br> begin<br> Inc(iRevDictRefCount,1);<br> if not Assigned(RevDictInstance) then<br> begin<br> RevDictInstance:=inherited Create;<br> //LoadDict(APath+words);<br> end ;<br> end;<br> 2:RevDictInstance:=nil;<br> else<br> raise Exception.CreateFmt(strCreateParamError,[ClassName]);<br> end;<br> <br> Result:=RevDictInstance;<br>end;<br><br>procedure TReverseDict.LoadDict(APath: string); //载入字典<br>var<br>nd,tmpNode:TCharTreeNode;<br>str:string;<br>index:Word;<br>i,j:LongWord;<br>{ItemChainElem; }<br>{isExsit:Boolean;}<br>F:TextFile;<br>PosDel1,PosDel2:Integer;<br>wfreq:string;<br><br>lst:TStringList;<br>sTip:string;<br> procedure Split(Splitor,Str:string); //sSubstr分割sStr,存入TStringList.<br> var<br> PSplitor,PStr,PPosChar;<br> s:string;<br> begin<br> PSplitor:=PChar(Splitor);<br> PStr:=PChar(Str);<br> PPos:=PChar(Str);<br><br> while PPos<>#0 do<br> begin<br> while (PPos^<>PSplitor^) and (PPos^<>#0) do inc(PPos);<br><br> SetString(S,PStr,PPos-PStr);<br> lst.Add(S);<br><br> if PPos^<>#0 then inc(PPos)<br> else break;<br><br> pstr:=ppos;<br> end;<br> end;<br>begin<br> FDictPath:=APath;<br> SetDictType(dtReveser); //指定字典属性<br><br> lst:=TStringList.Create;<br> try<br> AssignFile(F,Apath);<br> Reset(F);<br> try<br> while (not Eof(F)) do //把每一个词加载到树上<br> begin<br> Readln(F,str); //在字典中取词<br> sTip:=str;<br> <br> Split(#9,str);<br> str:=lst.Strings[1];<br> PosDel1:=Pos('"',str);<br> PosDel2:=LastDelimiter('"',str);<br> str:=Copy(str,PosDel1+1 ,PosDel2-PosDel1-1); //剔除双引号 ,找到词<br> if lst.Count>=3 then //词频<br> wfreq:=lst.Strings[2];<br><br> lst.Clear;<br> if Length(Trim(str))<=1 then Continue; //不是汉字(应该不会出现)<br> str:=AnsiReverseString(Trim(str)); //逆序<br><br> try<br> index:=word(Byte(str[1]) shl 8)+ word(Byte(str[2])); //树根节点索引<br> except<br> MessageDlg(Format(StrRowError,[sTip]),mtWarning,[mbOK],0);<br> Halt;<br> end;<br><br> nd:=Tree.root[index];<br><br> if Length(str)=2 then //单字词<br> begin<br> nd.WordFreq:=StrToIntDef(wFreq,1);<br> nd.WordEnd:=True;<br> continue ;<br> end;<br> for i:=1 to (Length(str) div 2)-1 do<br> begin<br> tmpNode:=FindCharacter(Copy(str,i*2+1,2),nd);<br> if tmpNode=nil then<br> nd:=nd.AddChild(Copy(str,i*2+1,2)) //值相等的节点不存在。追加。<br> else<br> begin<br> nd:=tmpNode;<br> Continue;<br> end;<br> Tree.Count:=tree.count+1; //树节点个数加1<br> end; //end 'for'<br><br> nd.WordFreq:=StrToIntdef(wfreq,1); //词频<br> nd.WordEnd:=True; //词结束标记<br> end;<br> except<br> MessageDlg(StrLoadDictError,mtInformation,[MBOK],0);<br> Abort;<br> end;<br> finally<br> CloseFile(F);<br> end;<br>end;<br><br><br>class function TReverseDict.PlusDict(APath: string): TInterfacedDict;<br>begin<br><br>end;<br><br>procedure TReverseDict.ReleaseInstance;<br>begin<br> Dec(iRevDictRefCount,1);<br> if iRevDictRefCount<=0 then<br> if GetInstance(0)<>nil then<br> GetInstance(0).Free;<br>end;<br><br><br><br><br><br><br><br>initialization<br> DictInstance:=nil;<br> RevDictInstance:=nil;<br><br> iRevDictRefCount:=0;<br> iDictRefCount:=0;<br>finalization<br> //...<br>end.