Develop and Download Open Source Software

Browse CVS Repository

Annotation of /gikonavigoeson/gikonavi/GikoBayesian.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download) (as text)
Thu Oct 21 03:18:44 2004 UTC (19 years, 6 months ago) by yoffy
Branch: MAIN
Changes since 1.3: +3 -3 lines
File MIME type: text/x-pascal
THashedStringList は遅いので使用を停止。

1 yoffy 1.1 unit GikoBayesian;
2    
3     {!
4     \file GikoBayesian.pas
5     \brief ???ゃ?吾?≪?潟???c????/span>
6    
7 yoffy 1.4 $Id: GikoBayesian.pas,v 1.3 2004/10/21 03:13:19 yoffy Exp $
8 yoffy 1.1 }
9    
10     interface
11    
12     //==================================================
13     uses
14     //==================================================
15 yoffy 1.4 Classes;
16 yoffy 1.1
17     //==================================================
18     type
19     //==================================================
20    
21     {!***********************************************************
22     \brief ??茯???????????/span>
23     ************************************************************}
24     TWordInfo = class( TObject )
25     private
26     FNormalWord : Integer; //!< ??絽吾????茯????????糸?眼????????/span>
27     FImportantWord : Integer; //!< 羈?????茯????????糸?眼????????/span>
28     FNormalText : Integer; //!< ??絽吾????茯??????????障??????????腴?????/span>
29     FImportantText : Integer; //!< 羈?????茯??????????障??????????腴?????/span>
30    
31     public
32     property NormalWord : Integer read FNormalWord write FNormalWord;
33     property ImportantWord : Integer read FImportantWord write FImportantWord;
34     property NormalText : Integer read FNormalText write FNormalText;
35     property ImportantText : Integer read FImportantText write FImportantText;
36     end;
37    
38     {!***********************************************************
39     \brief 茹f??羝??水??茯???????????/span>
40     ************************************************************}
41     TWordCountInfo = class( TObject )
42     private
43     FWordCount : Integer; //!< ??茯???/span>
44    
45     public
46     property WordCount : Integer read FWordCount write FWordCount;
47     end;
48    
49     {!***********************************************************
50     \brief 茹f??羝??水??茯????鴻??
51     ************************************************************}
52     // TWordCount = class( THashedStringList ) // 羶???
53 yoffy 1.3 TWordCount = class( TStringList )
54 yoffy 1.1 public
55 yoffy 1.3 constructor Create;
56 yoffy 1.1 destructor Destroy; override;
57     end;
58    
59     {!***********************************************************
60     \brief ???c???帥?≪???眼???冴??
61     ************************************************************}
62     TGikoBayesianAlgorithm =
63     (gbaPaulGraham, gbaGaryRonbinson{, gbaGaryRonbinsonFisher});
64    
65     {!***********************************************************
66     \brief ???ゃ?吾?≪?潟???c????/span>
67     ************************************************************}
68 yoffy 1.3 // TGikoBayesian = class( THashedStringList ) // 羶???
69     TGikoBayesian = class( TStringList )
70 yoffy 1.1 private
71     FFilePath : string; //!< 茯??粋昭???????<?ゃ??????/span>
72     function GetObject( const name : string ) : TWordInfo;
73     procedure SetObject( const name : string; value : TWordInfo );
74    
75     public
76     constructor Create;
77     destructor Destroy; override;
78    
79     //! ???<?ゃ??????絖??絮ユ???茯??水?冴???障??
80     procedure LoadFromFile( const filePath : string );
81    
82     //! ???<?ゃ?????膺?絮ユ???篆?絖????障??
83     procedure SaveToFile( const filePath : string );
84    
85     //! ???<?ゃ?????膺?絮ユ???篆?絖????障??
86     procedure Save;
87    
88     //! ??茯???????????宴????緇????障??
89     property Objects[ const name : string ] : TWordInfo
90     read GetObject write SetObject; default;
91    
92     //! ??腴??????障??????茯????????潟?????障??
93     procedure CountWord(
94     const text : string;
95     wordCount : TWordCount );
96    
97     {!
98     \brief Paul Graham 羈????冴?ャ??????腴???絵??墾??羆阪????障??
99     \return ??腴???絵??墾 (羈??????ゃ?????? 0.0??1.0 羈??????鴻??)
100     }
101     function CalcPaulGraham( wordCount : TWordCount ) : Extended;
102    
103     {!
104     \brief GaryRobinson 羈????冴?ャ??????腴???絵??墾??羆阪????障??
105     \return ??腴???絵??墾 (羈??????ゃ?????? 0.0??1.0 羈??????鴻??)
106     }
107     function CalcGaryRobinson( wordCount : TWordCount ) : Extended;
108    
109     // function CalcGaryRobinsonFisher( wordCount : TWordCount ) : Extended;
110    
111     {!
112     \brief ??腴???茹f??
113     \param text 茹f????????腴?
114     \param wordCount 茹f??????????茯????鴻????菴???
115     \param algorithm 羈???墾??浦絎??????????≪???眼???冴??????絎????障??
116     \return ??腴???絵??墾 (羈??????ゃ?????? 0.0??1.0 羈??????鴻??)
117    
118     CountWord ? Calcxxxxx ???障???????茵??????????с????
119     }
120     function Parse(
121     const text : string;
122     wordCount : TWordCount;
123     algorithm : TGikoBayesianAlgorithm = gbaGaryRonbinson
124     ) : Extended;
125    
126     {!
127     \brief 絖??????
128     \param wordCount Parse ?цВ??????????茯????鴻??
129     \param isImportant 羈??????鴻????腴???????????????? True
130     }
131     procedure Learn(
132     wordCount : TWordCount;
133     isImportant : Boolean );
134    
135     {!
136     \brief 絖??腟?????綽?????
137     \param wordCount Parse ?цВ??????????茯????鴻??
138     \param isImportant 羈??????鴻????腴???????????????????????? True
139     \warning 絖??羝??帥????腴???????????∈茯??堺?ャ?障??????<br>
140     Learn ????????????腴??? isImportant ???????c????????腴???
141     Forget ?????????若?帥???若?鴻???贋?????障????<br>
142     絖??羝??帥????????????????????????????????
143    
144     ???????膺?腟??????????≪????????с???????障??????<br>
145     wordCount ??緇?????腴? (Parse ? text 綣??? ???膺?腟??????帥?????≪???障????<br><br>
146    
147     筝祉??絵????腴?????羈?????腴????????帥????????? Forget -> Learn ?????т戎?????障????
148     }
149     procedure Forget(
150     wordCount : TWordCount;
151     isImportant : Boolean );
152     end;
153    
154     //==================================================
155     implementation
156     //==================================================
157    
158     uses
159 yoffy 1.4 SysUtils, Math, Windows;
160 yoffy 1.1
161     const
162     GIKO_BAYESIAN_FILE_VERSION = '1.0';
163 yoffy 1.3 {
164     Modes = (ModeWhite, ModeGraph, ModeAlpha, ModeHanKana, ModeNum,
165     ModeWGraph, ModeWAlpha, ModeWNum,
166     ModeWHira, ModeWKata, ModeWKanji);
167     }
168     CharMode1 : array [ 0..255 ] of Byte =
169     (
170     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
171     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
172     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
173     2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
174     1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
175     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1,
176     1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
177     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
178    
179     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
181     0, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
182     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
183     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
184     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1,
185     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
186     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
187     );
188 yoffy 1.1
189     //************************************************************
190     // misc
191     //************************************************************
192    
193     //==============================
194     // RemoveToken
195     //==============================
196     function RemoveToken(var s: string;const delimiter: string): string;
197     var
198     p: Integer;
199     begin
200     p := AnsiPos(delimiter, s);
201     if p = 0 then
202     Result := s
203     else
204     Result := Copy(s, 1, p - 1);
205     s := Copy(s, Length(Result) + Length(delimiter) + 1, Length(s));
206     end;
207    
208     //==============================
209     // AbsSort
210     //==============================
211     function AbsSort( p1, p2 : Pointer ) : Integer;
212     var
213     v1, v2 : Single;
214     begin
215    
216     v1 := Abs( Single( p1 ) - 0.5 );
217     v2 := Abs( Single( p2 ) - 0.5 );
218     if v1 > v2 then
219     Result := -1
220     else if v1 = v2 then
221     Result := 0
222     else
223     Result := 1;
224    
225     end;
226    
227     //************************************************************
228     // TWordCount class
229     //************************************************************
230 yoffy 1.3 constructor TWordCount.Create;
231     begin
232    
233     Duplicates := dupIgnore;
234     CaseSensitive := True;
235     Sorted := True;
236    
237     end;
238    
239 yoffy 1.1 destructor TWordCount.Destroy;
240     var
241     i : Integer;
242     begin
243    
244     for i := Count - 1 downto 0 do
245     if Objects[ i ] <> nil then
246     Objects[ i ].Free;
247    
248     inherited;
249    
250     end;
251    
252     //************************************************************
253     // TGikoBayesian class
254     //************************************************************
255    
256     //==============================
257     // Create
258     //==============================
259     constructor TGikoBayesian.Create;
260     begin
261    
262 yoffy 1.3 Duplicates := dupIgnore;
263     CaseSensitive := True;
264     Sorted := True;
265 yoffy 1.1
266     end;
267    
268     //==============================
269     // Destroy
270     //==============================
271     destructor TGikoBayesian.Destroy;
272     var
273     i : Integer;
274     begin
275    
276     for i := Count - 1 downto 0 do
277     if inherited Objects[ i ] <> nil then
278     inherited Objects[ i ].Free;
279    
280     inherited;
281    
282     end;
283    
284     procedure TGikoBayesian.LoadFromFile( const filePath : string );
285     var
286     i : Integer;
287     sl : TStringList;
288     s : string;
289     name : string;
290     info : TWordInfo;
291     begin
292    
293 yoffy 1.2 FFilePath := filePath;
294    
295 yoffy 1.1 if not FileExists( filePath ) then
296     Exit;
297 yoffy 1.2
298 yoffy 1.1 sl := TStringList.Create;
299     try
300     sl.LoadFromFile( filePath );
301    
302     for i := 1 to sl.Count - 1 do begin
303     s := sl[ i ];
304     name := RemoveToken( s, #1 );
305     info := TWordInfo.Create;
306     info.NormalWord := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 );
307     info.ImportantWord := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 );
308     info.NormalText := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 );
309     info.ImportantText := StrToIntDef( '$' + RemoveToken( s, #1 ), 0 );
310    
311     AddObject( name, info );
312     end;
313     finally
314     sl.Free;
315     end;
316    
317     end;
318    
319     procedure TGikoBayesian.SaveToFile( const filePath : string );
320     var
321     i : Integer;
322     sl : TStringList;
323     s : string;
324     info : TWordInfo;
325     begin
326    
327 yoffy 1.2 FFilePath := filePath;
328    
329 yoffy 1.1 sl := TStringList.Create;
330     try
331     sl.BeginUpdate;
332     sl.Add( GIKO_BAYESIAN_FILE_VERSION );
333    
334     for i := 0 to Count - 1 do begin
335     info := TWordInfo( inherited Objects[ i ] );
336     s := Strings[ i ] + #1
337     + Format('%x', [info.NormalWord]) + #1
338     + Format('%x', [info.ImportantWord]) + #1
339     + Format('%x', [info.NormalText]) + #1
340     + Format('%x', [info.ImportantText]);
341    
342     sl.Add(s);
343     end;
344     sl.EndUpdate;
345     sl.SaveToFile( filePath );
346     finally
347     sl.Free;
348     end;
349    
350     end;
351    
352     procedure TGikoBayesian.Save;
353     begin
354    
355     if FFilePath <> '' then
356     SaveToFile( FFilePath );
357    
358     end;
359    
360     //==============================
361     // GetObject
362     //==============================
363     function TGikoBayesian.GetObject( const name : string ) : TWordInfo;
364     var
365     idx : Integer;
366     begin
367    
368 yoffy 1.3 idx := IndexOf( name ); // 羶???
369 yoffy 1.1 if idx < 0 then
370     Result := nil
371     else
372     Result := TWordInfo( inherited Objects[ idx ] );
373    
374     end;
375    
376     //==============================
377     // SetObject
378     //==============================
379     procedure TGikoBayesian.SetObject( const name : string; value : TWordInfo );
380     var
381     idx : Integer;
382     begin
383    
384     idx := IndexOf( name );
385     if idx < 0 then
386     AddObject( name, value )
387     else
388     inherited Objects[ idx ] := value;
389    
390     end;
391    
392    
393     //==============================
394     // CountWord
395     //==============================
396     procedure TGikoBayesian.CountWord(
397     const text : string;
398     wordCount : TWordCount );
399     type
400 yoffy 1.3 Modes = (ModeWhite, ModeGraph, ModeAlpha, ModeHanKana, ModeNum,
401 yoffy 1.1 ModeWGraph, ModeWAlpha, ModeWNum,
402     ModeWHira, ModeWKata, ModeWKanji);
403     var
404     p, tail, last : PChar;
405     mode, newMode : Modes;
406     aWord : string;
407     ch : Longword;
408     chSize : Integer;
409     delimiter : TStringList;
410     delimited : Boolean;
411     i, idx : Integer;
412     countInfo : TWordCountInfo;
413     const
414     KAKUJOSI = '??' + #10 + '??#39; + #10 + '??' + #10 + '??#39; + #10 + '????' +
415     #10 + '??#39; + #10 + '??#39; + #10 + '????' + #10 + '?障??#39;;
416     begin
417    
418     delimiter := TStringList.Create;
419     try
420     mode := ModeWhite;
421     delimiter.Text := KAKUJOSI;
422     p := PChar( text );
423     tail := p + Length( text );
424     last := p;
425    
426     while p < tail do begin
427     delimited := False;
428     // ??絖????帥?ゃ?????ゅ??/span>
429     // ?糸???鴻? ModeGraph ?????????у???ャ???綽??????????????
430 yoffy 1.3 if Byte(Byte( p^ ) - $a1) < $5e then begin
431 yoffy 1.1 if p + 1 < tail then begin
432     ch := (PByte( p )^ shl 8) or PByte( p + 1 )^;
433     case ch of
434     $8140: newMode := ModeWhite;
435     $8141..$824e: newMode := ModeWGraph;
436     $824f..$8258: newMode := ModeWNum;
437     $8260..$829a: newMode := ModeWAlpha;
438     $829f..$82f1: newMode := ModeWHira;
439     $8340..$8396: newMode := ModeWKata;
440     else newMode := ModeWKanji;
441     end;
442     end else begin
443     newMode := ModeWhite;
444     end;
445    
446     chSize := 2;
447    
448     // ?阪????????????絖?????????罎??祉????
449     if p + 3 < tail then begin // 3 = delimiter ????紊у?? - 1
450     for i := 0 to delimiter.Count - 1 do begin
451     if CompareMem(
452     p, PChar( delimiter[ i ] ), Length( delimiter[ i ] ) ) then begin
453     delimited := True;
454     chSize := Length( delimiter[ i ] );
455     Break;
456     end;
457     end;
458     end;
459     end else begin
460 yoffy 1.3 // ????紊??????
461     newMode := Modes( CharMode1[ Byte( p^ ) ] );
462 yoffy 1.1
463     chSize := 1;
464     end;
465    
466     if (mode <> newMode) or delimited then begin
467    
468     // ??絖????帥?ゃ????紊??眼??????
469     // ????????阪????????????絖???????????
470     if mode <> ModeWhite then begin
471 yoffy 1.3 SetLength( aWord, p - last );
472     CopyMemory( PChar( aWord ), last, p - last );
473     idx := wordCount.IndexOf( aWord ); // ??
474 yoffy 1.1 if idx < 0 then begin
475     countInfo := TWordCountInfo.Create;
476     wordCount.AddObject( aWord, countInfo );
477     end else begin
478     countInfo := TWordCountInfo( wordCount.Objects[ idx ] );
479     end;
480     countInfo.WordCount := countInfo.WordCount + 1;
481     end;
482    
483     last := p;
484     mode := newMode;
485    
486     end;
487    
488     p := p + chSize;
489     end; // while
490    
491     if mode <> ModeWhite then begin
492     aWord := Copy( last, 0, p - last );
493     idx := wordCount.IndexOf( aWord );
494     if idx < 0 then begin
495     countInfo := TWordCountInfo.Create;
496     wordCount.AddObject( aWord, countInfo );
497     end else begin
498     countInfo := TWordCountInfo( wordCount.Objects[ idx ] );
499     end;
500     countInfo.WordCount := countInfo.WordCount + 1;
501     end;
502     finally
503     delimiter.Free;
504     end;
505    
506     end;
507    
508     //==============================
509     // CalcPaulGraham
510     //==============================
511     function TGikoBayesian.CalcPaulGraham( wordCount : TWordCount ) : Extended;
512    
513     function p( const aWord : string ) : Single;
514     var
515     info : TWordInfo;
516     begin
517     info := Objects[ aWord ];
518     if info = nil then
519     Result := 0.4
520     else if info.NormalWord = 0 then
521     Result := 0.99
522     else if info.ImportantWord = 0 then
523     Result := 0.01
524     else
525     Result := ( info.ImportantWord / info.ImportantText ) /
526     ((info.NormalWord * 2 / info.NormalText ) +
527     (info.ImportantWord / info.ImportantText));
528     end;
529    
530     var
531     s, q : Extended;
532     i : Integer;
533     narray : TList;
534     const
535     SAMPLE_COUNT = 15;
536     begin
537    
538     Result := 1;
539     if wordCount.Count = 0 then
540     Exit;
541    
542     narray := TList.Create;
543     try
544     for i := 0 to wordCount.Count - 1 do begin
545     narray.Add( Pointer( p( wordCount[ i ] ) ) );
546     end;
547    
548     narray.Sort( AbsSort );
549    
550     s := 1;
551     q := 1;
552     i := min( SAMPLE_COUNT, narray.Count );
553     while i > 0 do begin
554     Dec( i );
555     s := s * Single( narray[ i ] );
556     q := q * (1 - Single( narray[ i ] ));
557     end;
558    
559     Result := s / (s + q);
560     finally
561     narray.Free;
562     end;
563    
564     end;
565    
566     //==============================
567     // CalcGaryRobinson
568     //==============================
569     function TGikoBayesian.CalcGaryRobinson( wordCount : TWordCount ) : Extended;
570    
571     function p( const aWord : string ) : Single;
572     var
573     info : TWordInfo;
574     begin
575     info := Objects[ aWord ];
576     if info = nil then
577     Result := 0.415
578     else if info.ImportantWord = 0 then
579     Result := 0.0001
580     else if info.NormalWord = 0 then
581     Result := 0.9999
582     else
583     Result := ( info.ImportantWord / info.ImportantText ) /
584     ((info.NormalWord / info.NormalText ) +
585     (info.ImportantWord / info.ImportantText));
586     end;
587    
588     function f( cnt : Integer; n, mean : Single ) : Extended;
589     const
590     k = 0.00001;
591     begin
592     Result := ( (k * mean) + (cnt * n) ) / (k + cnt);
593     end;
594    
595     var
596     n : Extended;
597     narray : array of Single;
598     mean : Extended;
599     countInfo : TWordCountInfo;
600     i : Integer;
601     normal : Extended;
602     important : Extended;
603     cnt : Extended;
604     begin
605    
606     if wordCount.Count = 0 then begin
607     Result := 1;
608     Exit;
609     end;
610    
611     SetLength( narray, wordCount.Count );
612     mean := 0;
613     for i := 0 to wordCount.Count - 1 do begin
614     n := p( wordCount[ i ] );
615     narray[ i ] := n;
616     mean := mean + n;
617     end;
618     mean := mean / wordCount.Count;
619    
620     cnt := 0;
621     normal := 1;
622     important := 1;
623     for i := 0 to wordCount.Count - 1 do begin
624     countInfo := TWordCountInfo( wordCount.Objects[ i ] );
625     n := f( countInfo.WordCount, narray[ i ], mean );
626     normal := normal * n;
627     important := important * (1 - n);
628     if countInfo <> nil then
629     cnt := cnt + countInfo.WordCount;
630     end;
631     if cnt = 0 then
632     cnt := 1;
633     normal := 1 - Exp( Ln( normal ) * (1 / cnt) );
634     important := 1 - Exp( Ln( important ) * (1 / cnt) );
635    
636     n := (important - normal+ 0.00001) / (important + normal + 0.00001);
637     Result := (1 + n) / 2;
638    
639     end;
640    
641     //==============================
642     // Parse
643     //==============================
644     function TGikoBayesian.Parse(
645     const text : string;
646     wordCount : TWordCount;
647     algorithm : TGikoBayesianAlgorithm = gbaGaryRonbinson
648     ) : Extended;
649     begin
650    
651     CountWord( text, wordCount );
652     case algorithm of
653     gbaPaulGraham: Result := CalcPaulGraham( wordCount );
654     gbaGaryRonbinson: Result := CalcGaryRobinson( wordCount );
655     else Result := 0;
656     end;
657    
658     end;
659    
660     //==============================
661     // Learn
662     //==============================
663     procedure TGikoBayesian.Learn(
664     wordCount : TWordCount;
665     isImportant : Boolean );
666     var
667     aWord : string;
668     wordinfo : TWordInfo;
669     countinfo : TWordCountInfo;
670 yoffy 1.3 i : Integer;
671 yoffy 1.1 begin
672    
673     for i := 0 to wordCount.Count - 1 do begin
674     aWord := wordCount[ i ];
675     wordinfo := Objects[ aWord ];
676 yoffy 1.3 countinfo := TWordCountInfo( wordCount.Objects[ i ] );
677 yoffy 1.1 if wordinfo = nil then begin
678     wordinfo := TWordInfo.Create;
679     Objects[ aWord ] := wordinfo;
680     end;
681    
682     if isImportant then begin
683     wordinfo.ImportantWord := wordinfo.ImportantWord + countinfo.WordCount;
684     wordinfo.ImportantText := wordinfo.ImportantText + 1;
685     end else begin
686     wordinfo.NormalWord := wordinfo.NormalWord + countinfo.WordCount;
687     wordinfo.NormalText := wordinfo.NormalText + 1;
688     end;
689     end;
690    
691     end;
692    
693     //==============================
694     // Forget
695     //==============================
696     procedure TGikoBayesian.Forget(
697     wordCount : TWordCount;
698     isImportant : Boolean );
699     var
700     aWord : string;
701     wordinfo : TWordInfo;
702     countinfo : TWordCountInfo;
703     i : Integer;
704     begin
705    
706     for i := 0 to wordCount.Count - 1 do begin
707     aWord := wordCount[ i ];
708     wordinfo := Objects[ aWord ];
709     if wordinfo = nil then
710     Continue;
711    
712     countinfo := TWordCountInfo( wordCount.Objects[ i ] );
713     if isImportant then begin
714     wordinfo.ImportantWord := wordinfo.ImportantWord - countinfo.WordCount;
715     wordinfo.ImportantText := wordinfo.ImportantText - 1;
716     end else begin
717     wordinfo.NormalWord := wordinfo.NormalWord - countinfo.WordCount;
718     wordinfo.NormalText := wordinfo.NormalText - 1;
719     end;
720     end;
721    
722     end;
723    
724     end.

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26