How to compress and decompress repeated string characters by storing the repeated length (RLE) in Pascal

1 Answer

0 votes
program RLEPascal;

{$mode objfpc}  { modern Free Pascal mode }

uses
  SysUtils;

(* ---------------------------------------------------------
   Compress: turn "aaabbcccc" into "a3b2c4"
   This is run-length encoding (RLE)
   --------------------------------------------------------- *)
function Compress(const s: AnsiString): AnsiString;
var
  outStr: AnsiString;     // Result string
  count: Integer;         // Count of repeated characters
  i: Integer;
begin
  if s = '' then
  begin
    Result := '';         // Edge case: empty string
    Exit;
  end;

  outStr := '';
  count := 1;

  // Start from index 2 and compare with previous character
  for i := 2 to Length(s) + 1 do
  begin
    // If still repeating the same character, increase count
    if (i <= Length(s)) and (s[i] = s[i - 1]) then
      Inc(count)
    else
    begin
      // Character changed OR reached end of string
      outStr += s[i - 1];          // Add the character
      outStr += IntToStr(count);   // Add how many times it repeated
      count := 1;                  // Reset counter
    end;
  end;

  Result := outStr;
end;

(* ---------------------------------------------------------
   Decompress: turn "a3b2c4" into "aaabbcccc"
   Reads a letter, then reads digits, expands them.
   --------------------------------------------------------- *)
function Decompress(const s: AnsiString): AnsiString;
var
  outStr: AnsiString;     // Result string
  currentChar: Char;      // The character being processed
  number: AnsiString;     // Digits representing the count
  i, k, count: Integer;
  c: Char;
begin
  outStr := '';
  currentChar := #0;
  number := '';

  for i := 1 to Length(s) do
  begin
    c := s[i];

    if c in ['A'..'Z', 'a'..'z'] then   // Found a letter
    begin
      // If we already have a previous letter + number, expand it
      if (currentChar <> #0) and (number <> '') then
      begin
        count := StrToInt(number);
        for k := 1 to count do
          outStr += currentChar;
      end;

      currentChar := c;   // Start new character
      number := '';       // Reset number buffer
    end
    else if c in ['0'..'9'] then        // Found a digit
    begin
      number += c;        // Build multi-digit number
    end;
  end;

  // Handle the last character + number pair
  if (currentChar <> #0) and (number <> '') then
  begin
    count := StrToInt(number);
    for k := 1 to count do
      outStr += currentChar;
  end;

  Result := outStr;
end;

var
  s, c, d: AnsiString;

begin
  s := 'wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww';

  c := Compress(s);
  d := Decompress(c);

  WriteLn('Original:   ', s);
  WriteLn('Compressed: ', c);
  WriteLn('Decompressed: ', d);
end.



(*
run:

Original:   wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
Compressed: w12b1w10b3w6c4w12
Decompressed: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww

*)

 



answered 1 day ago by avibootz

Related questions

...