Найти и посчитать слова в строке в Delphi? - PullRequest
4 голосов
/ 02 сентября 2011

У меня есть строка, состоящая из множества слов.Как мне найти и посчитать общее количество раз, когда появляется определенное слово?

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

Как мне найти все слова "привет" в приведенном выше примере?

Спасибо.

Ответы [ 4 ]

16 голосов
/ 02 сентября 2011

В 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;
6 голосов
/ 02 сентября 2011

Я уверен, что есть много кода, чтобы делать подобные вещи, но достаточно легко сделать это самостоятельно с помощью 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

Примечание: я работаю с Delphi 2010, и у меня нет SplitString().

6 голосов
/ 02 сентября 2011

Это будет полностью зависеть от того, как вы определяете слово и текст, из которого вы хотите извлечь слова. Если «слово» - это все, что находится между пробелами, или «-» в вашем примере, тогда это становится довольно простой задачей. Однако, если вы хотите иметь дело со словами, сокращениями, сокращениями и т. Д., Написанными через дефис, это становится намного сложнее.

Больше информации, пожалуйста.

РЕДАКТИРОВАТЬ: после перечитывания вашего поста, и если приведенный вами пример является единственным, который вы хотите, то я бы предложил это:

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;

Это поймает ВСЕ экземпляры последовательности символов.

2 голосов
/ 05 сентября 2011

Очень умная реализация, которую я видел где-то в сети:

{ 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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...