2004. január 25., vasárnap

How to reverse a string


Problem/Question/Abstract:

How to reverse a string

Answer:

Here are three examples how to reverse a string:


#1, While easy to understand suffers from a lot of memory reallocation. Each time the next letter is added to s2, it's added to the beginning of the string causing a reallocation of the entire string.


function ReverseString(s: string): string;
var
  i: integer;
  s2: string;
begin
  s2 := '';
  for i := 1 to Length(s) do
    s2 := s[i] + s2;
  Result := s2;
end;


#2, Taking advantage of the fact that we can work at both ends of the string at once AND the fact that IF there is a middle character, ie. an odd number of characters in the string, it doesn't change position at all and we can eliminate all the memory allocations, work completely within the source string swapping from end to end working toward the middle and only having to make 1/2 of a loop through the string.



procedure ReverseStr(var Src: string);
var
  i, j: integer;
  C1: char;
begin
  j := Length(Src);
  for i := 1 to (Length(Src) div 2) do
  begin
    C1 := Src[i];
    Src[i] := Src[j];
    Src[j] := C1;
    Dec(j);
  end;
end;


#3, One disadvantage of #2 can be seen when trying to fill one control with the contents of another.  For example, two TEdits.  Since TEdit.Text can't be sent as a var parameter you'll need to first make use of a temporary string and then set the second TEdit:


var
  tStr: string;
begin
  tStr := Edit1.Text;
  ReverseStr(tStr);
  Edit2.Text := tStr;


However, using #3 this code turns into,


Edit2.Text := ReverseStr(Edit1.Text);

In addition, we lost 1 local var and the loop body was reduced since we could use Result directly swapping as we go!


function ReverseStr(const Src: string): string;
var
  i, j: integer;
begin
  j := Length(Src);
  SetLength(Result, j);
  for i := 1 to (Length(Src) div 2) do
  begin
    Result[i] := Src[j];
    Result[j] := Src[i];
    Dec(j);
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése