2011-09-02 56 views
4

我有一個包含大量單詞的字符串。如何查找並計算特定單詞出現的總次數?查找並計算字符串中的字在Delphi中?

E.g "hello-apple-banana-hello-pear" 

我會如何去找到上面的例子中的所有「你好」?

謝謝。

+0

查找特定的字符串可以用'AnsiPos'來完成和實現的計數是瑣碎'AnsiPos'。儘管這裏有很多缺陷,請給我們更多的背景信息。 –

回答

6

這完全取決於您如何定義單詞以及您希望從中拉出單詞的文本。如果一個「單詞」是空格之間的所有內容,或者在你的例子中是「 - 」,那麼它變成一個相當簡單的任務。但是,如果你想要處理帶有連字符的單詞,縮寫,縮寫等,那麼它變得更加困難。

請提供更多信息。

編輯:重讀您的帖子後,如果你給的例子是你想要的只有一個,那麼我建議這樣的:

function CountStr(const ASearchFor, ASearchIn : string) : Integer; 
var 
    Start : Integer; 
begin 
    Result := 0; 
    Start := Pos(ASearchFor, ASearchIn); 
    while Start > 0 do 
    begin 
     Inc(Result); 
     Start := PosEx(ASearchFor, ASearchIn, Start + 1); 
    end; 
end; 

這會趕上的字符序列的所有實例。

+3

如果您不重複序列(如「atat」)的次數超過一次,請更改while循環中的「Start:=」行以讀取「Start:= PosEx(ASearchFor,ASearchIn,Start + Length(ASearchFor ));' –

16

在Delphi XE中,您可以使用StrUtils.SplitString

像這樣的事情

var 
    Words: TstringDynArray; 
    Word: string; 
    WordCount: Integer; 
begin 
    WordCount := 0; 
    Words := SplitString('hello-apple-banana-hello-pear', '-'); 
    for Word in Words do 
    begin 
     if Word = 'hello' then 
      inc(WordCount); 
    end; 
+2

+1比任何使用'StrPos'更可讀的... – jpfollenius

6

我敢肯定有很多的代碼身邊做這樣的事情,但它是很容易與自己的Generics.Collections.TDictionary<K,V>的幫助下做到這一點。

program WordCount; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Character, Generics.Collections; 

function IsSeparator(const c: char): Boolean; 
begin 
    Result := TCharacter.IsWhiteSpace(c);//replace this with whatever you want 
end; 

procedure PopulateWordDictionary(const s: string; dict: TDictionary<string, Integer>); 

    procedure AddItem(Item: string); 
    var 
    Count: Integer; 
    begin 
    if Item='' then 
     exit; 
    Item := LowerCase(Item); 
    if dict.TryGetValue(Item, Count) then 
     dict[Item] := Count+1 
    else 
     dict.Add(Item, 1); 
    end; 

var 
    i, len, Start: Integer; 
    Item: string; 
begin 
    len := Length(s); 
    Start := 1; 
    for i := 1 to len do begin 
    if IsSeparator(s[i]) then begin 
     AddItem(Copy(s, Start, i-Start)); 
     Start := i+1; 
    end; 
    end; 
    AddItem(Copy(s, Start, len-Start+1)); 
end; 

procedure Main; 
var 
    dict: TDictionary<string, Integer>; 
    pair: TPair<string, Integer>; 
begin 
    dict := TDictionary<string, Integer>.Create; 
    try 
    PopulateWordDictionary('hello apple banana Hello pear', dict); 
    for pair in dict do 
     Writeln(pair.Key, ': ', pair.Value); 
    finally 
    dict.Free; 
    end; 
end; 

begin 
    try 
    Main; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

輸出:

hello: 2 
banana: 1 
apple: 1 
pear: 1 

注:我與德爾福2010年的工作,並沒有SplitString()使用。

2

一個非常聰明的實現我什麼地方看到過在網絡上:

{ Returns a count of the number of occurences of SubText in Text } 
function CountOccurences(const SubText: string; 
          const Text: string): Integer; 
begin 
    if (SubText = '') OR (Text = '') OR (Pos(SubText, Text) = 0) then 
    Result := 0 
    else 
    Result := (Length(Text) - Length(StringReplace(Text, SubText, '', [rfReplaceAll]))) div Length(subtext); 
end; { CountOccurences }