I am creating a programme where I am searching for vowels within a string, and after they have been found, the vowels need to be removed from the string.
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] := ''
but the error
Incompatible types: 'Char' and 'String' " appears
What can i do to delete the vowels from my string?
What you are looking for is a null character value. You are trying to use the empty string, which is an entity with zero length. But there is no character than has zero length. The null character value that you are looking for simply does not exist.
Another way to see this is to consider what Length(mystring)
is at the end of your loop. No matter what characters you assign with mystring[k] := ...
, the length of mystring
is never modified.
So, you could make a new string instead of modifying the existing one. For example:
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;
Or you could make repeated calls to StringReplace
:
mystring := StringReplace(mystring, 'a', '', [rfReplaceAll]);
mystring := StringReplace(mystring, 'e', '', [rfReplaceAll]);
//etc.
This version using StringReplace
is slower than the first approach.
Yet another approach would be to operate in place:
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);
Or this one:
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's code is probably faster, but this one doesn't need any additional string. Also, this one also takes care of upper-case vowels (if that's what you want).
Just another suggestion for your evaluation:
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]);
The ideia is to replace all the vowels by the character #1 (#0 doesn't work). The loop does that. Then, all #1 in the string are removed by replacing them by an empty string, what is achieved by the function StringReplace.
You can do it like :
localStr:=mystring;
mystring:='';
if ... then mystring:=mystring+localStr[i];
example
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;
Result mystring : Agst
For the experts :
Never thought the StringReplace
with only one sign, is so slow.
If string is 474000 bytes. This test takes 2 minutes and 5 seconds.
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) is only to show that delete downto is faster
The Test in seconds.
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.