word_freq.zig en Zig
Una tabla de frecuencia de palabras con tokenize, un hash map, un sort y un gráfico.
// Count word frequencies in a passage and chart the leaders.
const std = @import("std");
const passage = "the rain in maine falls mainly on the plain and " ++
"the rain stays on the plain";
const Entry = struct {
word: []const u8,
count: u32,
};
fn moreFirst(_: void, a: Entry, b: Entry) bool {
return a.count > b.count;
}
pub fn main() !void {
var gpa = std.heap.DebugAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Tally every word into a map keyed by its slice of the passage.
var counts = std.StringHashMap(u32).init(alloc);
defer counts.deinit();
var words = std.mem.tokenizeScalar(u8, passage, ' ');
while (words.next()) |w| {
const slot = try counts.getOrPut(w);
if (!slot.found_existing) slot.value_ptr.* = 0;
slot.value_ptr.* += 1;
}
// Pull the entries out and sort by count, biggest first.
var ranked = std.ArrayList(Entry).empty;
defer ranked.deinit(alloc);
var it = counts.iterator();
while (it.next()) |kv| {
try ranked.append(alloc, .{
.word = kv.key_ptr.*,
.count = kv.value_ptr.*,
});
}
std.mem.sort(Entry, ranked.items, {}, moreFirst);
std.debug.print("{d} distinct words\n", .{ranked.items.len});
std.debug.print("word ct bar\n", .{});
const bars = "####################";
for (ranked.items) |e| {
std.debug.print("{s:<7} {d:>2} {s}\n", .{
e.word, e.count, bars[0..e.count],
});
}
}
Cómo funciona
tokenizeScalarrecorre el pasaje;getOrPutcuenta cada palabra en una sonda.- Las entradas pasan a un
ArrayListystd.mem.sortlas ordena, la mayor primero. - Rebanar una barra de numerales hasta
e.countdibuja la línea de cada palabra.
Palabras clave y builtins usados aquí
boolconstdeferfnforifpubreturnstructtryu32u8varvoidwhile
El intento, en números
- Líneas
- 51
- Caracteres a escribir
- 1340
- Tokens
- 378
- Ritmo de tres estrellas
- 65 tpm
Al ritmo de tres estrellas de 65 tokens por minuto, este intento toma unos 349 segundos.
Paso 1 de 3 en Bis; paso 25 de 27 en Fundamentos del lenguaje.