diff --git a/codes/zig/build.zig b/codes/zig/build.zig index cc0a1f188..4ba9bea82 100644 --- a/codes/zig/build.zig +++ b/codes/zig/build.zig @@ -174,6 +174,19 @@ pub fn build(b: *std.build.Builder) void { const run_step_hash_map= b.step("run_hash_map", "Run hash_map"); run_step_hash_map.dependOn(&run_cmd_hash_map.step); + // Source File: "chapter_hashing/array_hash_map.zig" + // Run Command: zig build run_array_hash_map + const exe_array_hash_map = b.addExecutable("array_hash_map", "chapter_hashing/array_hash_map.zig"); + exe_array_hash_map.addPackagePath("include", "include/include.zig"); + exe_array_hash_map.setTarget(target); + exe_array_hash_map.setBuildMode(mode); + exe_array_hash_map.install(); + const run_cmd_array_hash_map = exe_array_hash_map.run(); + run_cmd_array_hash_map.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_array_hash_map.addArgs(args); + const run_step_array_hash_map= b.step("run_array_hash_map", "Run array_hash_map"); + run_step_array_hash_map.dependOn(&run_cmd_array_hash_map.step); + // Section: "Binary Tree" // Source File: "chapter_tree/binary_tree.zig" // Run Command: zig build run_binary_tree diff --git a/codes/zig/chapter_hashing/array_hash_map.zig b/codes/zig/chapter_hashing/array_hash_map.zig new file mode 100644 index 000000000..b87b53134 --- /dev/null +++ b/codes/zig/chapter_hashing/array_hash_map.zig @@ -0,0 +1,163 @@ +// File: array_hash_map.zig +// Created Time: 2023-01-15 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// 键值对 int->String +const Entry = struct { + key: usize = undefined, + val: []const u8 = undefined, + + pub fn init(key: usize, val: []const u8) Entry { + return Entry { + .key = key, + .val = val, + }; + } +}; + +// 基于数组简易实现的哈希表 +pub fn ArrayHashMap(comptime T: type) type { + return struct { + bucket: ?std.ArrayList(?T) = null, + mem_allocator: std.mem.Allocator = undefined, + + const Self = @This(); + + // 构造函数 + pub fn init(self: *Self, allocator: std.mem.Allocator) !void { + self.mem_allocator = allocator; + // 初始化一个长度为 100 的桶(数组) + self.bucket = std.ArrayList(?T).init(self.mem_allocator); + var i: i32 = 0; + while (i < 100) : (i += 1) { + try self.bucket.?.append(null); + } + } + + // 析构函数 + pub fn deinit(self: *Self) void { + if (self.bucket != null) self.bucket.?.deinit(); + } + + // 哈希函数 + fn hashFunc(key: usize) usize { + var index = key % 100; + return index; + } + + // 查询操作 + pub fn get(self: *Self, key: usize) []const u8 { + var index = hashFunc(key); + var pair = self.bucket.?.items[index]; + return pair.?.val; + } + + // 添加操作 + pub fn put(self: *Self, key: usize, val: []const u8) !void { + var pair = Entry.init(key, val); + var index = hashFunc(key); + self.bucket.?.items[index] = pair; + } + + // 删除操作 + pub fn remove(self: *Self, key: usize) !void { + var index = hashFunc(key); + // 置为 null ,代表删除 + self.bucket.?.items[index] = null; + } + + // 获取所有键值对 + pub fn entrySet(self: *Self) !*std.ArrayList(T) { + var entry_set = std.ArrayList(T).init(self.mem_allocator); + for (self.bucket.?.items) |item| { + if (item == null) continue; + try entry_set.append(item.?); + } + return &entry_set; + } + + // 获取所有键 + pub fn keySet(self: *Self) !*std.ArrayList(usize) { + var key_set = std.ArrayList(usize).init(self.mem_allocator); + for (self.bucket.?.items) |item| { + if (item == null) continue; + try key_set.append(item.?.key); + } + return &key_set; + } + + // 获取所有值 + pub fn valueSet(self: *Self) !*std.ArrayList([]const u8) { + var value_set = std.ArrayList([]const u8).init(self.mem_allocator); + for (self.bucket.?.items) |item| { + if (item == null) continue; + try value_set.append(item.?.val); + } + return &value_set; + } + + // 打印哈希表 + pub fn print(self: *Self) !void { + var entry_set = try self.entrySet(); + defer entry_set.deinit(); + for (entry_set.items) |item| { + std.debug.print("{} -> {s}\n", .{item.key, item.val}); + } + } + }; +} + +// Driver Code +pub fn main() !void { + // 初始化哈希表 + var map = ArrayHashMap(Entry){}; + try map.init(std.heap.page_allocator); + defer map.deinit(); + + // 添加操作 + // 在哈希表中添加键值对 (key, value) + try map.put(12836, "小哈"); + try map.put(15937, "小啰"); + try map.put(16750, "小算"); + try map.put(13276, "小法"); + try map.put(10583, "小鸭"); + std.debug.print("\n添加完成后,哈希表为\nKey -> Value\n", .{}); + try map.print(); + + // 查询操作 + // 向哈希表输入键 key ,得到值 value + var name = map.get(15937); + std.debug.print("\n输入学号 15937 ,查询到姓名 {s}\n", .{name}); + + // 删除操作 + // 在哈希表中删除键值对 (key, value) + try map.remove(10583); + std.debug.print("\n删除 10583 后,哈希表为\nKey -> Value\n", .{}); + try map.print(); + + // 遍历哈希表 + std.debug.print("\n遍历键值对 Key->Value\n", .{}); + var entry_set = try map.entrySet(); + for (entry_set.items) |kv| { + std.debug.print("{} -> {s}\n", .{kv.key, kv.val}); + } + entry_set.deinit(); + std.debug.print("\n单独遍历键 Key\n", .{}); + var key_set = try map.keySet(); + for (key_set.items) |key| { + std.debug.print("{}\n", .{key}); + } + key_set.deinit(); + std.debug.print("\n单独遍历值 value\n", .{}); + var value_set = try map.valueSet(); + for (value_set.items) |val| { + std.debug.print("{s}\n", .{val}); + } + value_set.deinit(); + + const getchar = try std.io.getStdIn().reader().readByte(); + _ = getchar; +} \ No newline at end of file