typestar

word_freq.pas en Delphi

Cuenta las palabras de un pasaje incrustado e imprime las cinco más comunes con barras.

program WordFreq;

uses SysUtils;

const
  Passage = 'The rain in Maine falls mainly on the plain, and the ' +
            'plain is where the rain in Maine stays. Rain, rain!';
  TopN = 5;

var
  Words: array of string;
  Counts: array of Integer;

// Add one to a word's tally, appending it the first time it shows up.
procedure Bump(const Item: string);
var
  I: Integer;
begin
  for I := 0 to High(Words) do
    if Words[I] = Item then
    begin
      Inc(Counts[I]);
      Exit;
    end;
  SetLength(Words, Length(Words) + 1);
  SetLength(Counts, Length(Counts) + 1);
  Words[High(Words)] := Item;
  Counts[High(Counts)] := 1;
end;

// Split on anything that is not a letter, folding case along the way.
procedure Tally(const Text: string);
var
  I: Integer;
  Token: string;
begin
  Token := '';
  for I := 1 to Length(Text) + 1 do
    if (I <= Length(Text)) and (Text[I] in ['a'..'z', 'A'..'Z']) then
      Token := Token + LowerCase(Text[I])
    else if Token <> '' then
    begin
      Bump(Token);   // the extra step flushes the last word
      Token := '';
    end;
end;

var
  I, J, Best, Swap: Integer;
  Held: string;
begin
  Tally(Passage);

  // Selection sort: pull the largest remaining count to the front.
  for I := 0 to High(Counts) - 1 do
  begin
    Best := I;
    for J := I + 1 to High(Counts) do
      if Counts[J] > Counts[Best] then
        Best := J;
    Swap := Counts[I]; Counts[I] := Counts[Best]; Counts[Best] := Swap;
    Held := Words[I]; Words[I] := Words[Best]; Words[Best] := Held;
  end;

  WriteLn(Format('%d distinct words', [Length(Words)]));
  WriteLn(Format('%-8s %5s  %s', ['word', 'count', 'bar']));
  for I := 0 to TopN - 1 do
    WriteLn(Format('%-8s %5d  %s',
      [Words[I], Counts[I], StringOfChar('#', Counts[I])]));
end.

Cómo funciona

  1. Bump busca coincidencia en Words y hace Inc(Counts[I]) o agrega un par con SetLength.
  2. Tally recorre el texto, guarda ['a'..'z', 'A'..'Z'] en minúscula y vacía Token en cada corte.
  3. Un orden por selección adelanta el mayor Counts[Best], y las filas dibujan barras con StringOfChar.

Palabras clave y builtins usados aquí

El intento, en números

Líneas
70
Caracteres a escribir
1617
Tokens
442
Ritmo de tres estrellas
75 tpm

Al ritmo de tres estrellas de 75 tokens por minuto, este intento toma unos 354 segundos.

Escribe este fragmento

Paso 1 de 3 en Bis; paso 25 de 27 en Fundamentos del lenguaje.

← Anterior Siguiente →