0

我正在创建一个程序,在其中搜索字符串中的元音,找到它们后,需要从字符串中删除元音。

 mystring := 'August'   ;

{if mystring[1] IN ['A','E','I','O','U'] ;}
for k := 1 to length(mystring) DO
BEGIN
if mystring[K] IN ['a','e','i','o','u']
then mystring[k] := ''

但错误

不兼容的类型:出现‘Char’和‘String’”

我该怎么做才能从字符串中删除元音?

4

4 回答 4

4

您正在寻找的是一个字符值。您正在尝试使用空字符串,它是一个长度为零的实体。但是没有长度为零的字符。您正在寻找的字符值根本不存在。

另一种看待这一点的方法是考虑Length(mystring)循环结束时的内容。无论您使用 分配什么字符,都不会修改mystring[k] := ...的长度。mystring

因此,您可以创建一个新字符串而不是修改现有字符串。例如:

var 
  new: string;
  len: Integer;
....
SetLength(new, Length(mystring));
len := 0;
for i := 1 to Length(mystring) do
begin
  if not (mystring[i] in ['a','e','i','o','u']) then
  begin
    inc(len);
    new[len] := mystring[i];
  end;
end;
SetLength(new, len);
mystring := new;

或者您可以反复调用StringReplace

mystring := StringReplace(mystring, 'a', '', [rfReplaceAll]);
mystring := StringReplace(mystring, 'e', '', [rfReplaceAll]);
//etc. 

这个版本使用StringReplace比第一种方法慢。

另一种方法是就地操作:

var 
  len: Integer;
....
len := 0;
for i := 1 to Length(mystring) do
begin
  if not (mystring[i] in ['a','e','i','o','u']) then
  begin
    inc(len);
    mystring[len] := mystring[i];
  end;
end;
SetLength(mystring, len);
于 2013-08-27T08:16:43.557 回答
1

只是对您的评估的另一个建议:

for i := 1 to Length(mystring) do
  if mystring[i] in ['a', 'e', 'i', 'o', 'u'] then
    mystring[i] := #1;
mystring := StringReplace(mystring, #1, '', [rfReplaceAll]);

想法是用字符#1#0不起作用)替换所有元音。循环就是这样做的。然后,字符串中的所有#1都通过用空字符串替换它们来删除,这由函数StringReplace实现。

于 2013-08-27T13:08:16.413 回答
1

你可以这样做:

localStr:=mystring;
mystring:='';
if ... then mystring:=mystring+localStr[i];

例子

mystring:= 'August';
...

var
localStr: string;
i       : Integer;
begin
localStr:=mystring;
mystring:='';
for i := 1 to Length(localStr) do if NOT ((localStr[i] in ['a','e','i','o','u'])) then
              mystring:=mystring+localStr[i];
end;

结果 mystring :Agst


对于专家:

没想到StringReplace只有一个标志,这么慢。
如果字符串是 474000 字节。此测试需要 2 分 5 秒。

User        Code in short
--------------------------------------------

David       inc(len) | new[len] := mystring[i] | SetLength(new, len)
David 2.    inc(len) | mystring[len] := mystring[i] | SetLength(mystring, len)
TLama       if not (C^ in CharSet) then | localStr[I] := C^ | Inc(I)
Me          localStr:=mystring | mystring:='' | mystring:=mystring+localStr[i]
AlexSc      mystring := StringReplace(mystring, #1, '', [rfReplaceAll])
HeartWare   I := 1                  | WHILE I<=LENGTH(MyString) DO  | DELETE(MyString,I,1) | INC(I)
 " DEC(I)   I := LENGTH(MyString)   | WHILE I > 0 DO                | DELETE(MyString,I,1) | DEC(I)

HeartWare DEC(I) 只是为了表明 delete downto 更快

几秒钟内的测试。

            length(mystring)--MB--------------------
            0.474       1.049       4.002       7.995       15.358      56.948
----------------------------------------------------                
Delphi 5 on XP
----------------------------------------------------            
TLama   :   0.003       0.016       0.047       0.078       0.172       0.687
David   :   0.003       0.016       0.047       0.093       0.192       0.765
David 2.:   0.003       0.016       0.063       0.109       0.219       0.875

Me      :   0.125       0.281       1.109       2.192       4.203
HeartWare:  27.284      131.057
 " DEC(I):  21.793      108.406
AlexSc  :   143.723     break > 8 min.

Rad XE4 on vista
----------------------------------------------------            
TLama   :   0.003       0.032       0.068       0.139       0.194
David   :   0.003       0.032       0.068       0.146       0.203
Me      :   0.094       0.172       0.481       0.921       1.576
HeartWare:  23.056      119.076
 " DEC(I):  17.519      103.319
AlexSc  :   125.082     break > 8 min.
于 2013-08-27T17:26:22.687 回答
1

或者这个:

VAR
  I : Cardinal;

BEGIN
  I:=1;
  WHILE I<=LENGTH(MyString) DO
    IF MyString[I] IN ['a','e','i','o','u','A','E','I','O','U'] THEN
      DELETE(MyString,I,1)
    ELSE
      INC(I)
END;

David 的代码可能更快,但是这个不需要任何额外的字符串。此外,这个也处理大写元音(如果这是你想要的)。

于 2013-08-27T12:06:15.847 回答