typestar

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

  1. tokenizeScalar recorre el pasaje; getOrPut cuenta cada palabra en una sonda.
  2. Las entradas pasan a un ArrayList y std.mem.sort las ordena, la mayor primero.
  3. Rebanar una barra de numerales hasta e.count dibuja la línea de cada palabra.

Palabras clave y builtins usados aquí

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.

Escribe este fragmento

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

← Anterior Siguiente →