【问题标题】:How to count number of occurrences of a certain char in string?如何计算字符串中某个字符的出现次数?
【发布时间】:2013-02-24 00:39:23
【问题描述】:

Delphi中如何计算某个字符在字符串中出现的次数?

例如,假设我有以下字符串,并想计算其中的逗号数:

S := '1,2,3';

那我想得到2作为结果。

【问题讨论】:

标签: delphi delphi-xe2 delphi-2010


【解决方案1】:

嗯...我错过了什么吗?为什么不只是...

      kSepChar:=',';//to count commas
      bLen:=length(sLineToCheck);
      bCount:=0;//The numer of kSepChars seen so far.
      bPosn:=1;//First character in string is at position 1
      for bPosn:=1 to bLen do begin
         if sLineToCheck[bPosn]=kSepChar then inc(bCount);
         end;//

【讨论】:

  • 这或多或少与接受的答案相同。
  • LU RD... 嗯...你说的很对,当然是。对不起,我错过了它以前在这里的出现。 (我已经使用论坛多年,确实有一些想法。抱歉错过了。)
【解决方案2】:

简单的解决方案和良好的性能(我为 Delphi 7 编写,但也适用于其他版本):

function CountOccurences(const ASubString: string; const AString: string): Integer;
var
  iOffset: Integer;
  iSubStrLen: Integer;
begin
  Result := 0;

  if (ASubString = '') or (AString = '') then
    Exit;

  iOffset := 1;
  iSubStrLen := Length(ASubString);
  while (True) do
  begin
    iOffset := PosEx(ASubString, AString, iOffset);
    if (iOffset = 0) then
      Break;
    Inc(Result);
    Inc(iOffset, iSubStrLen);
  end;
end;

【讨论】:

  • 该副本会使循环变慢。如果您使用带有偏移选项的System.PosAnsiStrings.PosEx,则可以不使用它。
  • 正确评论,谢谢。不幸的是,在 Delphi 7 中,Pos 函数没有 Offset 参数。
  • 如果你查看 StrUtils,你会发现 Delphi 7 中的 PosEx 函数。
【解决方案3】:

您可以将 StringReplace 函数的好处用作:

function OccurencesOfChar(ContentString:string; CharToCount:char):integer;
begin
   Result:= Length(ContentString)-Length(StringReplace(ContentString, CharToCount,'', [rfReplaceAll, rfIgnoreCase]));
end;

【讨论】:

  • 比简单的字符循环慢得多,并且(恕我直言)不太容易立即看到正确性。
【解决方案4】:

即使答案已被接受,我仍将在下面发布更通用的函数,因为我觉得它非常优雅。此解决方案用于计算字符串而不是字符的出现次数。

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

【讨论】:

  • 有趣的观点!也许您可以将第一条语句简化为Result := Pos(SubText, Text); if Result > 0 then... [+1]
  • 罗伯特真漂亮。
  • 这是病态和美丽 :) 显然它不是很有效,但代码背后的技巧本身就是编程应该的!
  • 可爱,但我不想在代码中找到它。如果您正在阅读某人的代码并遇到这种情况,您必须停下来思考它是如何工作的,然后检查它是否正确。代码应该清晰。对不起,但我不觉得这很优雅。对我来说,优雅意味着简洁且明显正确,小号 + 表示聪明。
  • 它也比简单的字符循环慢得多。
【解决方案5】:

如果您不处理大文本,这个可以完成这项工作

...

uses RegularExpressions;

...

function CountChar(const s: string; const c: char): integer;
begin
 Result:= TRegEx.Matches(s, c).Count
end;

【讨论】:

  • 为什么在 Delphi 上不好用?正则表达式非常擅长处理大文本体。
【解决方案6】:

对于那些更喜欢现代 Delphi 版本中的枚举器循环的人(并不比 Andreas 接受的解决方案更好,只是一种替代解决方案):

function OccurrencesOfChar(const ContentString: string;
  const CharToCount: char): integer;
var
  C: Char;
begin
  result := 0;
  for C in ContentString do
    if C = CharToCount then
      Inc(result);
end;

【讨论】:

    【解决方案7】:

    你可以使用这个简单的功能:

    function OccurrencesOfChar(const S: string; const C: char): integer;
    var
      i: Integer;
    begin
      result := 0;
      for i := 1 to Length(S) do
        if S[i] = C then
          inc(result);
    end;
    

    【讨论】:

    • 不能一行行吗?
    • @NareshKumar:是的,当然:OccurrencesOfChar(myString, ',')
    • +1 但 chr 是一个糟糕的名字,因为它已经有意义。我建议C
    • @AndreasRejbrand - 谢谢安德烈亚斯
    • +1。不错,干净的解决方案。 (我发布了一个等效的枚举器,仅供未来读者参考。)
    猜你喜欢
    • 2017-10-09
    • 2010-11-12
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2012-10-03
    相关资源
    最近更新 更多