RosettaCodeData/Task/Boyer-Moore-string-search/Zig/boyer-moore-string-search.zig
2025-08-11 18:05:26 -07:00

71 lines
2.1 KiB
Zig

const std = @import("std");
const print = std.debug.print;
const ArrayList = std.ArrayList;
const Allocator = std.mem.Allocator;
fn display(numbers: []const i32) void {
print("[", .{});
for (numbers, 0..) |num, i| {
if (i > 0) {
print(", ", .{});
}
print("{}", .{num});
}
print("]\n", .{});
}
fn stringSearchSingle(haystack: []const u8, needle: []const u8) i32 {
if (std.mem.indexOf(u8, haystack, needle)) |index| {
return @intCast(index);
}
return -1;
}
fn stringSearch(allocator: Allocator, haystack: []const u8, needle: []const u8) !ArrayList(i32) {
var result = ArrayList(i32).init(allocator);
var start: usize = 0;
while (start < haystack.len) {
const haystack_reduced = haystack[start..];
const index = stringSearchSingle(haystack_reduced, needle);
if (index >= 0) {
try result.append(@as(i32, @intCast(start)) + index);
start += @as(usize, @intCast(index)) + needle.len;
} else {
break;
}
}
return result;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const texts = [_][]const u8{
"GCTAGCTCTACGAGTCTA",
"GGCTATAATGCGTA",
"there would have been a time for such a word",
"needle need noodle needle",
"DKnuthusesandprogramsanimaginarycomputertheMIXanditsassociatedmachinecodeandassemblylanguages",
"Nearby farms grew an acre of alfalfa on the dairy's behalf, with bales of that alfalfa exchanged for milk."
};
const patterns = [_][]const u8{"TCTA", "TAATAAA", "word", "needle", "and", "alfalfa"};
for (texts, 0..) |text, i| {
print("text{} = {s}\n", .{ i + 1, text });
}
print("\n" ,.{});
for (texts, 0..) |text, i| {
var indexes = try stringSearch(allocator, text, patterns[i]);
defer indexes.deinit();
print("Found \"{s}\" in 'text{}' at indexes ", .{ patterns[i], i + 1 });
display(indexes.items);
}
}