假设我的字符串是:

"The   fox   jumped   over    the log."

那么它应该变成:

"The fox jumped over the log."

在不循环和拆分字符串的情况下实现此目的最简单的(1-3 行)是什么?

6

  • 3
    “没有循环……”让这个问题很奇怪。 “简单”是什么意思?队伍可以排多长?为什么不创建一个超级棒的CollapseWhitespace函数(带循环),然后在每次需要时调用它?


    – 


  • 您忽略了格式设置,现在(由于 HTML 功能)您的两个示例看起来相同。


    – 

  • 1
    恕我直言,没有循环是不可能的


    – 

  • 1
    函数 Magic(const _InString: string): string; begin Result := ‘狐狸跳过了圆木。’;结尾;不幸的是,如果格式正确的话,这将超过 3 行。好吧,说真的:我认为您正在寻找一个可以简单调用的 RTL 函数。据我所知没有这样的功能。是一个类似的问题,有几个答案,但它们都包含循环并且超过 3 行。


    – 


  • 你的要求太奇怪了,这个问题有家庭作业的味道。家庭作业问题并不被禁止,但公平竞争要求您告知事实。因此我没有回答你的问题。


    – 



5 个回答
5

由于标签中有 FreePascal,因此在 Free Pascal 中使用

… DelSpace1 返回 S 的副本,其中所有空格序列都减少为 1 个空格。

这是一篇单行…

  WHILE (pos('  ', s) > 0) DO s := StringReplace(s, '  ', ' ', [rfReplaceAll]);

…然而,在代码格式化后,它将变成两行。它使用了一个循环,这在某种程度上与问题相反。

1

  • 这确实是一个正确的做法,但也是一种效率极低的做法(就运行时而言),


    – 

Delphi RTL 根本没有任何用于折叠连续空格的函数。您只需为此编写自己的循环,例如:

// this is just an example, there are many
// different ways you can implement this
// more efficiently, ie using a TStringBuilder,
// or even modifying the String in-place...
function CollapseSpaces(const S: string): string;
var
  P: PChar;
  AddSpace: Boolean;
begin
  Result := '';
  AddSpace := False;
  P := PChar(S);
  while P^ <> #0 do
  begin
    while CharInSet(P^, [#1..' ']) do Inc(P);
    if P^ = #0 then Exit;
    if AddSpace then
      Result := Result + ' '
    else
      AddSpace := True;
    repeat
      Result := Result + P^;
      Inc(P);
    until P^ <= ' ';
  end;
end;
var S: String;
S := 'The   fox   jumped   over    the log.'
S := CollapseSpaces(S);

没有循环:

Result := StringReplace(StringReplace(S, '   ', ' ', [rfReplaceAll]), '  ', ' ', [rfReplaceAll]);

解释:

  • 它首先用一个空格替换所有出现的三个连续空格
  • 然后将所有出现的两个连续空格替换为一个空格

替代方案(未经测试):

Result := String.Join(' ', StrUtils.SplitString(S, ' '));

6

  • 2
    这将失败'test test',这将给出test test


    – 

  • @AndreasRejbrand我知道存在局限性,但它在给定的输入上效果很好。 Q没有说必须支持最多多少个空格,所以我作弊了。


    – 

  • 恕我直言,在这种情况下最好对原始 Q 投反对票。


    – 

  • @AndreasRejbrand,这就是这个网站急剧下滑的原因之一。与其向社区中的新人解释以更好地解释问题并成为更好的开发人员,不如让我们对他们投反对票并让他们被封禁。


    – 

  • 1
    @mjnStrUtils.SplitString(S, ' ')将分割每个单独的空间,它不会折叠连续的空间。


    – 

str := string.Join(' ','The   fox   jumped   over    the log.'.Split([' '], TStringSplitOptions.ExcludeEmpty));

2

  • 适用于 Delphi 和 Free Pascal,非常感谢


    – 


  • –