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
Bumpbusca coincidencia enWordsy haceInc(Counts[I])o agrega un par conSetLength.Tallyrecorre el texto, guarda['a'..'z', 'A'..'Z']en minúscula y vacíaTokenen cada corte.- Un orden por selección adelanta el mayor
Counts[Best], y las filas dibujan barras conStringOfChar.
Palabras clave y builtins usados aquí
ExitFormatHighIncIntegerLengthLowerCaseSetLengthStringOfCharSwapWriteLnandarraybeginconstdoelseendforifinofprocedureprogramstringthentousesvar
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.
Paso 1 de 3 en Bis; paso 25 de 27 en Fundamentos del lenguaje.