diff --git a/codes/zig/build.zig b/codes/zig/build.zig index b04b3fd1..e72ca4a5 100644 --- a/codes/zig/build.zig +++ b/codes/zig/build.zig @@ -1,46 +1,67 @@ +// File: build.zig +// Created Time: 2023-01-07 +// Author: sjinzh (sjinzh@gmail.com) + const std = @import("std"); -// zig version 0.10.0 +// Zig Version: 0.10.0 +// Zig Codes Build Command: zig build pub fn build(b: *std.build.Builder) void { const target = b.standardTargetOptions(.{}); const mode = b.standardReleaseOptions(); - // "chapter_computational_complexity/time_complexity.zig" - // Run Command: zig build run_time_complexity - const exe_time_complexity = b.addExecutable("time_complexity", "chapter_computational_complexity/time_complexity.zig"); - exe_time_complexity.addPackagePath("include", "include/include.zig"); - exe_time_complexity.setTarget(target); - exe_time_complexity.setBuildMode(mode); - exe_time_complexity.install(); - const run_cmd_time_complexity = exe_time_complexity.run(); - run_cmd_time_complexity.step.dependOn(b.getInstallStep()); - if (b.args) |args| run_cmd_time_complexity.addArgs(args); - const run_step_time_complexity = b.step("run_time_complexity", "Run time_complexity"); - run_step_time_complexity.dependOn(&run_cmd_time_complexity.step); + // Section: "Time Complexity" + // File: "chapter_computational_complexity/time_complexity.zig" + // Run Command: zig build run_time_complexity + const exe_time_complexity = b.addExecutable("time_complexity", "chapter_computational_complexity/time_complexity.zig"); + exe_time_complexity.addPackagePath("include", "include/include.zig"); + exe_time_complexity.setTarget(target); + exe_time_complexity.setBuildMode(mode); + exe_time_complexity.install(); + const run_cmd_time_complexity = exe_time_complexity.run(); + run_cmd_time_complexity.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_time_complexity.addArgs(args); + const run_step_time_complexity = b.step("run_time_complexity", "Run time_complexity"); + run_step_time_complexity.dependOn(&run_cmd_time_complexity.step); - // "chapter_computational_complexity/worst_best_time_complexity.zig" - // Run Command: zig build run_worst_best_time_complexity - const exe_worst_best_time_complexity = b.addExecutable("worst_best_time_complexity", "chapter_computational_complexity/worst_best_time_complexity.zig"); - exe_worst_best_time_complexity.addPackagePath("include", "include/include.zig"); - exe_worst_best_time_complexity.setTarget(target); - exe_worst_best_time_complexity.setBuildMode(mode); - exe_worst_best_time_complexity.install(); - const run_cmd_worst_best_time_complexity = exe_worst_best_time_complexity.run(); - run_cmd_worst_best_time_complexity.step.dependOn(b.getInstallStep()); - if (b.args) |args| run_cmd_worst_best_time_complexity.addArgs(args); - const run_step_worst_best_time_complexity = b.step("run_worst_best_time_complexity", "Run worst_best_time_complexity"); - run_step_worst_best_time_complexity.dependOn(&run_cmd_worst_best_time_complexity.step); + // File: "chapter_computational_complexity/worst_best_time_complexity.zig" + // Run Command: zig build run_worst_best_time_complexity + const exe_worst_best_time_complexity = b.addExecutable("worst_best_time_complexity", "chapter_computational_complexity/worst_best_time_complexity.zig"); + exe_worst_best_time_complexity.addPackagePath("include", "include/include.zig"); + exe_worst_best_time_complexity.setTarget(target); + exe_worst_best_time_complexity.setBuildMode(mode); + exe_worst_best_time_complexity.install(); + const run_cmd_worst_best_time_complexity = exe_worst_best_time_complexity.run(); + run_cmd_worst_best_time_complexity.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_worst_best_time_complexity.addArgs(args); + const run_step_worst_best_time_complexity = b.step("run_worst_best_time_complexity", "Run worst_best_time_complexity"); + run_step_worst_best_time_complexity.dependOn(&run_cmd_worst_best_time_complexity.step); - // "chapter_computational_complexity/leetcode_two_sum.zig" - // Run Command: zig build run_leetcode_two_sum - const exe_leetcode_two_sum = b.addExecutable("leetcode_two_sum", "chapter_computational_complexity/leetcode_two_sum.zig"); - exe_leetcode_two_sum.addPackagePath("include", "include/include.zig"); - exe_leetcode_two_sum.setTarget(target); - exe_leetcode_two_sum.setBuildMode(mode); - exe_leetcode_two_sum.install(); - const run_cmd_leetcode_two_sum = exe_leetcode_two_sum.run(); - run_cmd_leetcode_two_sum.step.dependOn(b.getInstallStep()); - if (b.args) |args| run_cmd_leetcode_two_sum.addArgs(args); - const run_step_leetcode_two_sum = b.step("run_leetcode_two_sum", "Run leetcode_two_sum"); - run_step_leetcode_two_sum.dependOn(&run_cmd_leetcode_two_sum.step); + // Section: "Space Complexity" + // File: "chapter_computational_complexity/space_complexity.zig" + // Run Command: zig build run_space_complexity + const exe_space_complexity = b.addExecutable("space_complexity", "chapter_computational_complexity/space_complexity.zig"); + exe_space_complexity.addPackagePath("include", "include/include.zig"); + exe_space_complexity.setTarget(target); + exe_space_complexity.setBuildMode(mode); + exe_space_complexity.install(); + const run_cmd_space_complexity = exe_space_complexity.run(); + run_cmd_space_complexity.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_space_complexity.addArgs(args); + const run_step_space_complexity = b.step("run_space_complexity", "Run space_complexity"); + run_step_space_complexity.dependOn(&run_cmd_space_complexity.step); + + // Section: "Space Time Tradeoff" + // File: "chapter_computational_complexity/leetcode_two_sum.zig" + // Run Command: zig build run_leetcode_two_sum + const exe_leetcode_two_sum = b.addExecutable("leetcode_two_sum", "chapter_computational_complexity/leetcode_two_sum.zig"); + exe_leetcode_two_sum.addPackagePath("include", "include/include.zig"); + exe_leetcode_two_sum.setTarget(target); + exe_leetcode_two_sum.setBuildMode(mode); + exe_leetcode_two_sum.install(); + const run_cmd_leetcode_two_sum = exe_leetcode_two_sum.run(); + run_cmd_leetcode_two_sum.step.dependOn(b.getInstallStep()); + if (b.args) |args| run_cmd_leetcode_two_sum.addArgs(args); + const run_step_leetcode_two_sum = b.step("run_leetcode_two_sum", "Run leetcode_two_sum"); + run_step_leetcode_two_sum.dependOn(&run_cmd_leetcode_two_sum.step); } diff --git a/codes/zig/chapter_computational_complexity/space_complexity.zig b/codes/zig/chapter_computational_complexity/space_complexity.zig new file mode 100644 index 00000000..9798821a --- /dev/null +++ b/codes/zig/chapter_computational_complexity/space_complexity.zig @@ -0,0 +1,125 @@ +// File: space_complexity.zig +// Created Time: 2023-01-07 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); +const inc = @import("include"); + +// 函数 +fn function() i32 { + // do something + return 0; +} + +// 常数阶 +fn constant(n: i32) void { + // 常量、变量、对象占用 O(1) 空间 + const a: i32 = 0; + var b: i32 = 0; + var nums = [_]i32{0}**10000; + var node = inc.ListNode(i32){.val = 0}; + var i: i32 = 0; + // 循环中的变量占用 O(1) 空间 + while (i < n) : (i += 1) { + var c: i32 = 0; + _ = c; + } + // 循环中的函数占用 O(1) 空间 + i = 0; + while (i < n) : (i += 1) { + _ = function(); + } + _ = a; + _ = b; + _ = nums; + _ = node; +} + +// 线性阶 +fn linear(comptime n: i32) !void { + // 长度为 n 的数组占用 O(n) 空间 + var nums = [_]i32{0}**n; + // 长度为 n 的列表占用 O(n) 空间 + var nodes = std.ArrayList(i32).init(std.heap.page_allocator); + defer nodes.deinit(); + var i: i32 = 0; + while (i < n) : (i += 1) { + try nodes.append(i); + } + // 长度为 n 的哈希表占用 O(n) 空间 + var map = std.AutoArrayHashMap(i32, []const u8).init(std.heap.page_allocator); + defer map.deinit(); + var j: i32 = 0; + while (j < n) : (j += 1) { + const string = try std.fmt.allocPrint(std.heap.page_allocator, "{d}", .{j}); + defer std.heap.page_allocator.free(string); + try map.put(i, string); + } + _ = nums; +} + +// 线性阶(递归实现) +fn linearRecur(comptime n: i32) void { + std.debug.print("递归 n = {}\n", .{n}); + if (n == 1) return; + linearRecur(n - 1); +} + +// 平方阶 +fn quadratic(n: i32) !void { + // 二维列表占用 O(n^2) 空间 + var nodes = std.ArrayList(std.ArrayList(i32)).init(std.heap.page_allocator); + defer nodes.deinit(); + var i: i32 = 0; + while (i < n) : (i += 1) { + var tmp = std.ArrayList(i32).init(std.heap.page_allocator); + defer tmp.deinit(); + var j: i32 = 0; + while (j < n) : (j += 1) { + try tmp.append(0); + } + try nodes.append(tmp); + } +} + +// 平方阶(递归实现) +fn quadraticRecur(comptime n: i32) i32 { + if (n <= 0) return 0; + var nums = [_]i32{0}**n; + std.debug.print("递归 n = {} 中的 nums 长度 = {}\n", .{n, nums.len}); + return quadraticRecur(n - 1); +} + +// 指数阶(建立满二叉树) +fn buildTree(mem_allocator: std.mem.Allocator, n: i32) !?*inc.TreeNode(i32) { + if (n == 0) return null; + const root = try mem_allocator.create(inc.TreeNode(i32)); + root.init(0); + root.left = try buildTree(mem_allocator, n - 1); + root.right = try buildTree(mem_allocator, n - 1); + return root; +} + +// Driver Code +pub fn main() !void { + const n: i32 = 5; + // 常数阶 + constant(n); + // 线性阶 + try linear(n); + linearRecur(n); + // 平方阶 + try quadratic(n); + _ = quadraticRecur(n); + // 指数阶 + var mem_arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer mem_arena.deinit(); + var root = blk_root: { + const mem_allocator = mem_arena.allocator(); + break :blk_root try buildTree(mem_allocator, n); + }; + try inc.PrintUtil.printTree(root, null, false); + + const getchar = try std.io.getStdIn().reader().readByte(); + _ = getchar; +} \ No newline at end of file diff --git a/codes/zig/include/ListNode.zig b/codes/zig/include/ListNode.zig new file mode 100644 index 00000000..8ce01d3e --- /dev/null +++ b/codes/zig/include/ListNode.zig @@ -0,0 +1,20 @@ +// File: ListNode.zig +// Created Time: 2023-01-07 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); + +// Definition for a singly-linked list node +pub fn ListNode(comptime T: type) type { + return struct { + const Self = @This(); + + val: T = 0, + next: ?*Self = null, + + // Initialize a list node with specific value + pub fn init(self: *Self, x: i32) void { + self.val = x; + } + }; +} \ No newline at end of file diff --git a/codes/zig/include/PrintUtil.zig b/codes/zig/include/PrintUtil.zig index 5adac2a6..8a7dca7a 100644 --- a/codes/zig/include/PrintUtil.zig +++ b/codes/zig/include/PrintUtil.zig @@ -1,13 +1,72 @@ -// File: TreeNode.zig +// File: PrintUtil.zig // Created Time: 2023-01-07 // Author: sjinzh (sjinzh@gmail.com) const std = @import("std"); +const ListNode = @import("ListNode.zig").ListNode; +const TreeNode = @import("TreeNode.zig").TreeNode; -// Print an Array +// Print an array pub fn printArray(comptime T: type, nums: []T) void { std.debug.print("[", .{}); - for (nums) |num, j| { - std.debug.print("{}{s}", .{num, if (j == nums.len-1) "]\n" else ", " }); - } + if (nums.len > 0) { + for (nums) |num, j| { + std.debug.print("{}{s}", .{num, if (j == nums.len-1) "]\n" else ", " }); + } + } else { + std.debug.print("]", .{}); + std.debug.print("\n", .{}); + } } + +// This tree printer is borrowed from TECHIE DELIGHT +// https://www.techiedelight.com/c-program-print-binary-tree/ +const Trunk = struct { + prev: ?*Trunk = null, + str: []const u8 = undefined, + + pub fn init(self: *Trunk, prev: ?*Trunk, str: []const u8) void { + self.prev = prev; + self.str = str; + } +}; + +// Helper function to print branches of the binary tree +pub fn showTrunks(p: ?*Trunk) void { + if (p == null) return; + showTrunks(p.?.prev); + std.debug.print("{s}", .{p.?.str}); +} + +// The interface of the tree printer +// Print a binary tree +pub fn printTree(root: ?*TreeNode(i32), prev: ?*Trunk, isLeft: bool) !void { + if (root == null) { + return; + } + + var prev_str = " "; + var trunk = Trunk{.prev = prev, .str = prev_str}; + + try printTree(root.?.right, &trunk, true); + + if (prev == null) { + trunk.str = "———"; + } else if (isLeft) { + trunk.str = "/———"; + prev_str = " |"; + } else { + trunk.str = "\\———"; + prev.?.str = prev_str; + } + + showTrunks(&trunk); + std.debug.print(" {}\n", .{root.?.val}); + + if (prev) |_| { + prev.?.str = prev_str; + } + trunk.str = " |"; + + try printTree(root.?.left, &trunk, false); +} \ No newline at end of file diff --git a/codes/zig/include/TreeNode.zig b/codes/zig/include/TreeNode.zig new file mode 100644 index 00000000..9bd51ba3 --- /dev/null +++ b/codes/zig/include/TreeNode.zig @@ -0,0 +1,21 @@ +// File: TreeNode.zig +// Created Time: 2023-01-07 +// Author: sjinzh (sjinzh@gmail.com) + +const std = @import("std"); + +// Definition for a binary tree node +pub fn TreeNode(comptime T: type) type { + return struct { + const Self = @This(); + + val: T = undefined, + left: ?*Self = null, + right: ?*Self = null, + + // Initialize a tree node with specific value + pub fn init(self: *Self, x: i32) void { + self.val = x; + } + }; +} \ No newline at end of file diff --git a/codes/zig/include/include.zig b/codes/zig/include/include.zig index b4f34782..20dfca90 100644 --- a/codes/zig/include/include.zig +++ b/codes/zig/include/include.zig @@ -1,5 +1,7 @@ // File: include.zig -// Created Time: 2023-01-04 +// Created Time: 2023-01-07 // Author: sjinzh (sjinzh@gmail.com) -pub const PrintUtil = @import("PrintUtil.zig"); \ No newline at end of file +pub const PrintUtil = @import("PrintUtil.zig"); +pub const ListNode = @import("ListNode.zig").ListNode; +pub const TreeNode = @import("TreeNode.zig").TreeNode; \ No newline at end of file