【问题标题】:How to accurately count words in a Memo?如何准确计算备忘录中的单词?
【发布时间】:2021-02-16 12:11:46
【问题描述】:

我正在尝试制作记事本克隆,并在状态栏中添加了运行字数统计功能。字数不准确,将重复的空格或回车视为新单词。以下是我尝试过的字数统计功能:

procedure TFormMain.Memo1Change(Sender: TObject);
var
  wordSeparatorSet: Set of Char;
  count: integer;
  i: integer;
  s: string;
  inWord: Boolean;
begin
  wordSeparatorSet := [#13, #32]; // CR, space
  count := 0;
  s := Memo1.Text;
  inWord := False;

  for i := 1 to Length(s) do
  begin
    // if the char is a CR or space, you're at the end of a word; increase the count
    if (s[i] in wordSeparatorSet) and (inWord=True) then
    begin
      Inc(count);
      inWord := False;
    end
    else
    // the char is not a delimiter, so you're in a word
    begin
      inWord := True;
    end;
  end;
  // OK, all done counting. If you're still inside a word, don't forget to count it too
  if inWord then
    Inc(count);

  StatusBar1.Panels[0].Text := 'Words: ' + IntToStr(count);
end;

当然,我愿意接受任何替代方案或改进。我真的不明白为什么这段代码会增加每个空格和回车的字数(count)。我认为在用户按下空格键(递增count)后,变量inWord 现在应该为False,因此如果用户再次按下空格键或Enter 键,if (s[i] in wordSeparatorSet) and (inWord=True) 应该解析为False。但事实并非如此。

【问题讨论】:

标签: delphi word-count


【解决方案1】:

我真的不明白为什么这段代码会增加每个空格和回车的字数 (count)。

在单词后的第一个空格处,您确实将inWord 设置为False。因此,如果下一个字符也是空格,您将(错误地)运行inWord := True,因此如果下一个(第三个)字符再次是空格,您将(错误地)运行Inc(count)

您还可以注意到,(s[i] in wordSeparatorSet) and (inWord=True) 的否定并不意味着“字符不是分隔符”,因为它与 inWord 结合使用。 (s[i] in wordSeparatorSet) and (inWord=True) 的否定是De Morgannot (s[i] in wordSeparatorSet) or not (inWord=True),与not (s[i] in wordSeparatorSet) 不同。

固定版本看起来更像

function WordCount(const AText: string): Integer;
var
  InWord: Boolean;
  i: Integer;
begin
  Result := 0;
  InWord := False;
  for i := 1 to Length(AText) do
    if InWord then
    begin
      if IsWordSep(AText[i]) then
        InWord := False;
    end
    else
    begin
      if not IsWordSep(AText[i]) then
      begin
        InWord := True;
        Inc(Result);
      end;
    end;
end;

IsWordSep(chr) 被定义为类似于 chr.IsWhitespace 的东西,但其中有许多微妙之处,正如我详细讨论的 on my web site

【讨论】:

    猜你喜欢
    • 2019-07-26
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多