diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index 38a3f083..4923d9ec 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -299,5 +299,25 @@ path = "chapter_backtracking/permutations_i.rs" name = "permutations_ii" path = "chapter_backtracking/permutations_ii.rs" +# Run Command: cargo run --bin preorder_traversal_i_compact +[[bin]] +name = "preorder_traversal_i_compact" +path = "chapter_backtracking/preorder_traversal_i_compact.rs" + +# Run Command: cargo run --bin preorder_traversal_ii_compact +[[bin]] +name = "preorder_traversal_ii_compact" +path = "chapter_backtracking/preorder_traversal_ii_compact.rs" + +# Run Command: cargo run --bin preorder_traversal_iii_compact +[[bin]] +name = "preorder_traversal_iii_compact" +path = "chapter_backtracking/preorder_traversal_iii_compact.rs" + +# Run Command: cargo run --bin preorder_traversal_iii_template +[[bin]] +name = "preorder_traversal_iii_template" +path = "chapter_backtracking/preorder_traversal_iii_template.rs" + [dependencies] -rand = "0.8.5" +rand = "0.8.5" \ No newline at end of file diff --git a/codes/rust/chapter_backtracking/preorder_traversal_i_compact.rs b/codes/rust/chapter_backtracking/preorder_traversal_i_compact.rs new file mode 100644 index 00000000..0e618228 --- /dev/null +++ b/codes/rust/chapter_backtracking/preorder_traversal_i_compact.rs @@ -0,0 +1,43 @@ +/* + * File: preorder_traversal_i_compact.rs + * Created Time: 2023-07-15 + * Author: sjinzh (sjinzh@gmail.com) + */ + + include!("../include/include.rs"); + +use std::{cell::RefCell, rc::Rc}; +use tree_node::{vec_to_tree, TreeNode}; + +/* 前序遍历:例题一 */ +fn pre_order(res: &mut Vec>>, root: Option>>) { + if root.is_none() { + return; + } + if let Some(node) = root { + if node.borrow().val == 7 { + // 记录解 + res.push(node.clone()); + } + pre_order(res, node.borrow().left.clone()); + pre_order(res, node.borrow().right.clone()); + } +} + +/* Driver Code */ +pub fn main() { + let root = vec_to_tree([1, 7, 3, 4, 5, 6, 7].map(|x| Some(x)).to_vec()); + println!("初始化二叉树"); + print_util::print_tree(root.as_ref().unwrap()); + + // 前序遍历 + let mut res = Vec::new(); + pre_order(&mut res, root); + + println!("\n输出所有值为 7 的节点"); + let mut vals = Vec::new(); + for node in res { + vals.push(node.borrow().val) + } + println!("{:?}", vals); +} diff --git a/codes/rust/chapter_backtracking/preorder_traversal_ii_compact.rs b/codes/rust/chapter_backtracking/preorder_traversal_ii_compact.rs new file mode 100644 index 00000000..920cfab0 --- /dev/null +++ b/codes/rust/chapter_backtracking/preorder_traversal_ii_compact.rs @@ -0,0 +1,50 @@ +/* + * File: preorder_traversal_ii_compact.rs + * Created Time: 2023-07-15 + * Author: sjinzh (sjinzh@gmail.com) + */ + + include!("../include/include.rs"); + +use std::{cell::RefCell, rc::Rc}; +use tree_node::{vec_to_tree, TreeNode}; + +/* 前序遍历:例题二 */ +fn pre_order(res: &mut Vec>>>, path: &mut Vec>>, root: Option>>) { + if root.is_none() { + return; + } + if let Some(node) = root { + // 尝试 + path.push(node.clone()); + if node.borrow().val == 7 { + // 记录解 + res.push(path.clone()); + } + pre_order(res, path, node.borrow().left.clone()); + pre_order(res, path, node.borrow().right.clone()); + // 回退 + path.remove(path.len() - 1); + } +} + +/* Driver Code */ +pub fn main() { + let root = vec_to_tree([1, 7, 3, 4, 5, 6, 7].map(|x| Some(x)).to_vec()); + println!("初始化二叉树"); + print_util::print_tree(root.as_ref().unwrap()); + + // 前序遍历 + let mut path = Vec::new(); + let mut res = Vec::new(); + pre_order(&mut res, &mut path, root); + + println!("\n输出所有根节点到节点 7 的路径"); + for path in res { + let mut vals = Vec::new(); + for node in path { + vals.push(node.borrow().val) + } + println!("{:?}", vals); + } +} diff --git a/codes/rust/chapter_backtracking/preorder_traversal_iii_compact.rs b/codes/rust/chapter_backtracking/preorder_traversal_iii_compact.rs new file mode 100644 index 00000000..eaa046f2 --- /dev/null +++ b/codes/rust/chapter_backtracking/preorder_traversal_iii_compact.rs @@ -0,0 +1,51 @@ +/* + * File: preorder_traversal_iii_compact.rs + * Created Time: 2023-07-15 + * Author: sjinzh (sjinzh@gmail.com) + */ + + include!("../include/include.rs"); + +use std::{cell::RefCell, rc::Rc}; +use tree_node::{vec_to_tree, TreeNode}; + +/* 前序遍历:例题三 */ +fn pre_order(res: &mut Vec>>>, path: &mut Vec>>, root: Option>>) { + // 剪枝 + if root.is_none() || root.as_ref().unwrap().borrow().val == 3 { + return; + } + if let Some(node) = root { + // 尝试 + path.push(node.clone()); + if node.borrow().val == 7 { + // 记录解 + res.push(path.clone()); + } + pre_order(res, path, node.borrow().left.clone()); + pre_order(res, path, node.borrow().right.clone()); + // 回退 + path.remove(path.len() - 1); + } +} + +/* Driver Code */ +pub fn main() { + let root = vec_to_tree([1, 7, 3, 4, 5, 6, 7].map(|x| Some(x)).to_vec()); + println!("初始化二叉树"); + print_util::print_tree(root.as_ref().unwrap()); + + // 前序遍历 + let mut path = Vec::new(); + let mut res = Vec::new(); + pre_order(&mut res, &mut path, root); + + println!("\n输出所有根节点到节点 7 的路径,且路径中不包含值为 3 的节点"); + for path in res { + let mut vals = Vec::new(); + for node in path { + vals.push(node.borrow().val) + } + println!("{:?}", vals); + } +} diff --git a/codes/rust/chapter_backtracking/preorder_traversal_iii_template.rs b/codes/rust/chapter_backtracking/preorder_traversal_iii_template.rs new file mode 100644 index 00000000..15dfff50 --- /dev/null +++ b/codes/rust/chapter_backtracking/preorder_traversal_iii_template.rs @@ -0,0 +1,77 @@ +/* + * File: preorder_traversal_iii_template.rs + * Created Time: 2023-07-15 + * Author: sjinzh (sjinzh@gmail.com) + */ + + include!("../include/include.rs"); + +use std::{cell::RefCell, rc::Rc}; +use tree_node::{vec_to_tree, TreeNode}; + +/* 判断当前状态是否为解 */ +fn is_solution(state: &mut Vec>>) -> bool { + return !state.is_empty() && state.get(state.len() - 1).unwrap().borrow().val == 7; +} + +/* 记录解 */ +fn record_solution(state: &mut Vec>>, res: &mut Vec>>>) { + res.push(state.clone()); +} + +/* 判断在当前状态下,该选择是否合法 */ +fn is_valid(_: &mut Vec>>, choice: Rc>) -> bool { + return choice.borrow().val != 3; +} + +/* 更新状态 */ +fn make_choice(state: &mut Vec>>, choice: Rc>) { + state.push(choice); +} + +/* 恢复状态 */ +fn undo_choice(state: &mut Vec>>, _: Rc>) { + state.remove(state.len() - 1); +} + +/* 回溯算法:例题三 */ +fn backtrack(state: &mut Vec>>, choices: &mut Vec>>, res: &mut Vec>>>) { + // 检查是否为解 + if is_solution(state) { + // 记录解 + record_solution(state, res); + return; + } + // 遍历所有选择 + for choice in choices { + // 剪枝:检查选择是否合法 + if is_valid(state, choice.clone()) { + // 尝试:做出选择,更新状态 + make_choice(state, choice.clone()); + // 进行下一轮选择 + backtrack(state, &mut vec![choice.borrow().left.clone().unwrap(), choice.borrow().right.clone().unwrap()], res); + // 回退:撤销选择,恢复到之前的状态 + undo_choice(state, choice.clone()); + } + } +} + +/* Driver Code */ +pub fn main() { + let root = vec_to_tree([1, 7, 3, 4, 5, 6, 7].map(|x| Some(x)).to_vec()); + println!("初始化二叉树"); + print_util::print_tree(root.as_ref().unwrap()); + + // 回溯算法 + let mut res = Vec::new(); + backtrack(&mut Vec::new(), &mut vec![root.unwrap()], &mut res); + + println!("\n输出所有根节点到节点 7 的路径,要求路径中不包含值为 3 的节点"); + for path in res { + let mut vals = Vec::new(); + for node in path { + vals.push(node.borrow().val) + } + println!("{:?}", vals); + } +} diff --git a/codes/zig/chapter_dynamic_programming/climbing_stairs_backtrack.zig b/codes/zig/chapter_dynamic_programming/climbing_stairs_backtrack.zig index 0fc5ef10..b5adbbfb 100644 --- a/codes/zig/chapter_dynamic_programming/climbing_stairs_backtrack.zig +++ b/codes/zig/chapter_dynamic_programming/climbing_stairs_backtrack.zig @@ -23,7 +23,7 @@ fn backtrack(choices: []i32, state: i32, n: i32, res: std.ArrayList(i32)) void { } // 爬楼梯:回溯 -fn climbing_stairs_backtrack(n: usize) !i32 { +fn climbingStairsBacktrack(n: usize) !i32 { var choices = [_]i32{ 1, 2 }; // 可选择向上爬 1 或 2 阶 var state: i32 = 0; // 从第 0 阶开始爬 var res = std.ArrayList(i32).init(std.heap.page_allocator); @@ -37,7 +37,7 @@ fn climbing_stairs_backtrack(n: usize) !i32 { pub fn main() !void { var n: usize = 9; - var res = try climbing_stairs_backtrack(n); + var res = try climbingStairsBacktrack(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/climbing_stairs_constraint_dp.zig b/codes/zig/chapter_dynamic_programming/climbing_stairs_constraint_dp.zig index cd4e43ee..ce2619c3 100644 --- a/codes/zig/chapter_dynamic_programming/climbing_stairs_constraint_dp.zig +++ b/codes/zig/chapter_dynamic_programming/climbing_stairs_constraint_dp.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 带约束爬楼梯:动态规划 -fn climbing_stairs_constraint_dp(comptime n: usize) i32 { +fn climbingStairsConstraintDP(comptime n: usize) i32 { if (n == 1 or n == 2) { return @intCast(n); } @@ -28,7 +28,7 @@ fn climbing_stairs_constraint_dp(comptime n: usize) i32 { pub fn main() !void { comptime var n: usize = 9; - var res = climbing_stairs_constraint_dp(n); + var res = climbingStairsConstraintDP(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs.zig b/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs.zig index 2126a508..3a8250f9 100644 --- a/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs.zig +++ b/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs.zig @@ -16,7 +16,7 @@ fn dfs(i: usize) i32 { } // 爬楼梯:搜索 -fn climbing_stairs_dfs(comptime n: usize) i32 { +fn climbingStairsDFS(comptime n: usize) i32 { return dfs(n); } @@ -24,7 +24,7 @@ fn climbing_stairs_dfs(comptime n: usize) i32 { pub fn main() !void { comptime var n: usize = 9; - var res = climbing_stairs_dfs(n); + var res = climbingStairsDFS(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs_mem.zig b/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs_mem.zig index e29d1a29..a244af81 100644 --- a/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs_mem.zig +++ b/codes/zig/chapter_dynamic_programming/climbing_stairs_dfs_mem.zig @@ -22,7 +22,7 @@ fn dfs(i: usize, mem: []i32) i32 { } // 爬楼梯:记忆化搜索 -fn climbing_stairs_dfs_mem(comptime n: usize) i32 { +fn climbingStairsDFSMem(comptime n: usize) i32 { // mem[i] 记录爬到第 i 阶的方案总数,-1 代表无记录 var mem = [_]i32{ -1 } ** (n + 1); return dfs(n, &mem); @@ -32,7 +32,7 @@ fn climbing_stairs_dfs_mem(comptime n: usize) i32 { pub fn main() !void { comptime var n: usize = 9; - var res = climbing_stairs_dfs_mem(n); + var res = climbingStairsDFSMem(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/climbing_stairs_dp.zig b/codes/zig/chapter_dynamic_programming/climbing_stairs_dp.zig index 49641273..3b6d275f 100644 --- a/codes/zig/chapter_dynamic_programming/climbing_stairs_dp.zig +++ b/codes/zig/chapter_dynamic_programming/climbing_stairs_dp.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 爬楼梯:动态规划 -fn climbing_stairs_dp(comptime n: usize) i32 { +fn climbingStairsDP(comptime n: usize) i32 { // 已知 dp[1] 和 dp[2] ,返回之 if (n == 1 or n == 2) { return @intCast(n); @@ -23,7 +23,7 @@ fn climbing_stairs_dp(comptime n: usize) i32 { } // 爬楼梯:状态压缩后的动态规划 -fn climbing_stairs_dp_comp(comptime n: usize) i32 { +fn climbingStairsDPComp(comptime n: usize) i32 { if (n == 1 or n == 2) { return @intCast(n); } @@ -41,10 +41,10 @@ fn climbing_stairs_dp_comp(comptime n: usize) i32 { pub fn main() !void { comptime var n: usize = 9; - var res = climbing_stairs_dp(n); + var res = climbingStairsDP(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); - res = climbing_stairs_dp_comp(n); + res = climbingStairsDPComp(n); std.debug.print("爬 {} 阶楼梯共有 {} 种方案\n", .{ n, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/coin_change.zig b/codes/zig/chapter_dynamic_programming/coin_change.zig index 280237c6..772355e1 100644 --- a/codes/zig/chapter_dynamic_programming/coin_change.zig +++ b/codes/zig/chapter_dynamic_programming/coin_change.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 零钱兑换:动态规划 -fn coin_change_dp(comptime coins: []i32, comptime amt: usize) i32 { +fn coinChangeDP(comptime coins: []i32, comptime amt: usize) i32 { comptime var n = coins.len; comptime var max = amt + 1; // 初始化 dp 表 @@ -34,7 +34,7 @@ fn coin_change_dp(comptime coins: []i32, comptime amt: usize) i32 { } // 零钱兑换:状态压缩后的动态规划 -fn coin_change_dp_comp(comptime coins: []i32, comptime amt: usize) i32 { +fn coinChangeDPComp(comptime coins: []i32, comptime amt: usize) i32 { comptime var n = coins.len; comptime var max = amt + 1; // 初始化 dp 表 @@ -66,11 +66,11 @@ pub fn main() !void { comptime var amt: usize = 4; // 动态规划 - var res = coin_change_dp(&coins, amt); + var res = coinChangeDP(&coins, amt); std.debug.print("凑到目标金额所需的最少硬币数量为 {}\n", .{res}); // 状态压缩后的动态规划 - res = coin_change_dp_comp(&coins, amt); + res = coinChangeDPComp(&coins, amt); std.debug.print("凑到目标金额所需的最少硬币数量为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/coin_change_ii.zig b/codes/zig/chapter_dynamic_programming/coin_change_ii.zig index f556db1f..b3eba3d1 100644 --- a/codes/zig/chapter_dynamic_programming/coin_change_ii.zig +++ b/codes/zig/chapter_dynamic_programming/coin_change_ii.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 零钱兑换 II:动态规划 -fn coin_change_ii_dp(comptime coins: []i32, comptime amt: usize) i32 { +fn coinChangeIIDP(comptime coins: []i32, comptime amt: usize) i32 { comptime var n = coins.len; // 初始化 dp 表 var dp = [_][amt + 1]i32{[_]i32{0} ** (amt + 1)} ** (n + 1); @@ -29,7 +29,7 @@ fn coin_change_ii_dp(comptime coins: []i32, comptime amt: usize) i32 { } // 零钱兑换 II:状态压缩后的动态规划 -fn coin_change_dp_ii_comp(comptime coins: []i32, comptime amt: usize) i32 { +fn coinChangeIIDPComp(comptime coins: []i32, comptime amt: usize) i32 { comptime var n = coins.len; // 初始化 dp 表 var dp = [_]i32{0} ** (amt + 1); @@ -55,11 +55,11 @@ pub fn main() !void { comptime var amt: usize = 5; // 动态规划 - var res = coin_change_ii_dp(&coins, amt); + var res = coinChangeIIDP(&coins, amt); std.debug.print("凑出目标金额的硬币组合数量为 {}\n", .{res}); // 状态压缩后的动态规划 - res = coin_change_dp_ii_comp(&coins, amt); + res = coinChangeIIDPComp(&coins, amt); std.debug.print("凑出目标金额的硬币组合数量为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/edit_distance.zig b/codes/zig/chapter_dynamic_programming/edit_distance.zig index 0adbb95d..618d1ee0 100644 --- a/codes/zig/chapter_dynamic_programming/edit_distance.zig +++ b/codes/zig/chapter_dynamic_programming/edit_distance.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 编辑距离:暴力搜索 -fn edit_distance_dfs(comptime s: []const u8, comptime t: []const u8, i: usize, j: usize) i32 { +fn editDistanceDFS(comptime s: []const u8, comptime t: []const u8, i: usize, j: usize) i32 { // 若 s 和 t 都为空,则返回 0 if (i == 0 and j == 0) { return 0; @@ -20,18 +20,18 @@ fn edit_distance_dfs(comptime s: []const u8, comptime t: []const u8, i: usize, j } // 若两字符相等,则直接跳过此两字符 if (s[i - 1] == t[j - 1]) { - return edit_distance_dfs(s, t, i - 1, j - 1); + return editDistanceDFS(s, t, i - 1, j - 1); } // 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 - var insert = edit_distance_dfs(s, t, i, j - 1); - var delete = edit_distance_dfs(s, t, i - 1, j); - var replace = edit_distance_dfs(s, t, i - 1, j - 1); + var insert = editDistanceDFS(s, t, i, j - 1); + var delete = editDistanceDFS(s, t, i - 1, j); + var replace = editDistanceDFS(s, t, i - 1, j - 1); // 返回最少编辑步数 return @min(@min(insert, delete), replace) + 1; } // 编辑距离:记忆化搜索 -fn edit_distance_dfs_mem(comptime s: []const u8, comptime t: []const u8, mem: anytype, i: usize, j: usize) i32 { +fn editDistanceDFSMem(comptime s: []const u8, comptime t: []const u8, mem: anytype, i: usize, j: usize) i32 { // 若 s 和 t 都为空,则返回 0 if (i == 0 and j == 0) { return 0; @@ -50,19 +50,19 @@ fn edit_distance_dfs_mem(comptime s: []const u8, comptime t: []const u8, mem: an } // 若两字符相等,则直接跳过此两字符 if (s[i - 1] == t[j - 1]) { - return edit_distance_dfs_mem(s, t, mem, i - 1, j - 1); + return editDistanceDFSMem(s, t, mem, i - 1, j - 1); } // 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1 - var insert = edit_distance_dfs_mem(s, t, mem, i, j - 1); - var delete = edit_distance_dfs_mem(s, t, mem, i - 1, j); - var replace = edit_distance_dfs_mem(s, t, mem, i - 1, j - 1); + var insert = editDistanceDFSMem(s, t, mem, i, j - 1); + var delete = editDistanceDFSMem(s, t, mem, i - 1, j); + var replace = editDistanceDFSMem(s, t, mem, i - 1, j - 1); // 记录并返回最少编辑步数 mem[i][j] = @min(@min(insert, delete), replace) + 1; return mem[i][j]; } // 编辑距离:动态规划 -fn edit_distance_dp(comptime s: []const u8, comptime t: []const u8) i32 { +fn editDistanceDP(comptime s: []const u8, comptime t: []const u8) i32 { comptime var n = s.len; comptime var m = t.len; var dp = [_][m + 1]i32{[_]i32{0} ** (m + 1)} ** (n + 1); @@ -89,7 +89,7 @@ fn edit_distance_dp(comptime s: []const u8, comptime t: []const u8) i32 { } // 编辑距离:状态压缩后的动态规划 -fn edit_distance_dp_comp(comptime s: []const u8, comptime t: []const u8) i32 { +fn editDistanceDPComp(comptime s: []const u8, comptime t: []const u8) i32 { comptime var n = s.len; comptime var m = t.len; var dp = [_]i32{0} ** (m + 1); @@ -126,20 +126,20 @@ pub fn main() !void { comptime var m = t.len; // 暴力搜索 - var res = edit_distance_dfs(s, t, n, m); + var res = editDistanceDFS(s, t, n, m); std.debug.print("将 {s} 更改为 {s} 最少需要编辑 {} 步\n", .{ s, t, res }); // 记忆搜索 var mem = [_][m + 1]i32{[_]i32{-1} ** (m + 1)} ** (n + 1); - res = edit_distance_dfs_mem(s, t, @constCast(&mem), n, m); + res = editDistanceDFSMem(s, t, @constCast(&mem), n, m); std.debug.print("将 {s} 更改为 {s} 最少需要编辑 {} 步\n", .{ s, t, res }); // 动态规划 - res = edit_distance_dp(s, t); + res = editDistanceDP(s, t); std.debug.print("将 {s} 更改为 {s} 最少需要编辑 {} 步\n", .{ s, t, res }); // 状态压缩后的动态规划 - res = edit_distance_dp_comp(s, t); + res = editDistanceDPComp(s, t); std.debug.print("将 {s} 更改为 {s} 最少需要编辑 {} 步\n", .{ s, t, res }); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/knapsack.zig b/codes/zig/chapter_dynamic_programming/knapsack.zig index e591e4a4..9c67b405 100644 --- a/codes/zig/chapter_dynamic_programming/knapsack.zig +++ b/codes/zig/chapter_dynamic_programming/knapsack.zig @@ -5,24 +5,24 @@ const std = @import("std"); // 0-1 背包:暴力搜索 -fn knapsack_dfs(wgt: []i32, val: []i32, i: usize, c: usize) i32 { +fn knapsackDFS(wgt: []i32, val: []i32, i: usize, c: usize) i32 { // 若已选完所有物品或背包无容量,则返回价值 0 if (i == 0 or c == 0) { return 0; } // 若超过背包容量,则只能不放入背包 if (wgt[i - 1] > c) { - return knapsack_dfs(wgt, val, i - 1, c); + return knapsackDFS(wgt, val, i - 1, c); } // 计算不放入和放入物品 i 的最大价值 - var no = knapsack_dfs(wgt, val, i - 1, c); - var yes = knapsack_dfs(wgt, val, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1]; + var no = knapsackDFS(wgt, val, i - 1, c); + var yes = knapsackDFS(wgt, val, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1]; // 返回两种方案中价值更大的那一个 return @max(no, yes); } // 0-1 背包:记忆化搜索 -fn knapsack_dfs_mem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i32 { +fn knapsackDFSMem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i32 { // 若已选完所有物品或背包无容量,则返回价值 0 if (i == 0 or c == 0) { return 0; @@ -33,18 +33,18 @@ fn knapsack_dfs_mem(wgt: []i32, val: []i32, mem: anytype, i: usize, c: usize) i3 } // 若超过背包容量,则只能不放入背包 if (wgt[i - 1] > c) { - return knapsack_dfs_mem(wgt, val, mem, i - 1, c); + return knapsackDFSMem(wgt, val, mem, i - 1, c); } // 计算不放入和放入物品 i 的最大价值 - var no = knapsack_dfs_mem(wgt, val, mem, i - 1, c); - var yes = knapsack_dfs_mem(wgt, val, mem, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1]; + var no = knapsackDFSMem(wgt, val, mem, i - 1, c); + var yes = knapsackDFSMem(wgt, val, mem, i - 1, c - @as(usize, @intCast(wgt[i - 1]))) + val[i - 1]; // 记录并返回两种方案中价值更大的那一个 mem[i][c] = @max(no, yes); return mem[i][c]; } // 0-1 背包:动态规划 -fn knapsack_dp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { +fn knapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { comptime var n = wgt.len; // 初始化 dp 表 var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1); @@ -64,7 +64,7 @@ fn knapsack_dp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { } // 0-1 背包:状态压缩后的动态规划 -fn knapsack_dp_comp(wgt: []i32, val: []i32, comptime cap: usize) i32 { +fn knapsackDPComp(wgt: []i32, val: []i32, comptime cap: usize) i32 { var n = wgt.len; // 初始化 dp 表 var dp = [_]i32{0} ** (cap + 1); @@ -90,20 +90,20 @@ pub fn main() !void { comptime var n = wgt.len; // 暴力搜索 - var res = knapsack_dfs(&wgt, &val, n, cap); + var res = knapsackDFS(&wgt, &val, n, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); // 记忆搜索 var mem = [_][cap + 1]i32{[_]i32{-1} ** (cap + 1)} ** (n + 1); - res = knapsack_dfs_mem(&wgt, &val, @constCast(&mem), n, cap); + res = knapsackDFSMem(&wgt, &val, @constCast(&mem), n, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); // 动态规划 - res = knapsack_dp(&wgt, &val, cap); + res = knapsackDP(&wgt, &val, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); // 状态压缩后的动态规划 - res = knapsack_dp_comp(&wgt, &val, cap); + res = knapsackDPComp(&wgt, &val, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/min_cost_climbing_stairs_dp.zig b/codes/zig/chapter_dynamic_programming/min_cost_climbing_stairs_dp.zig index 29bdb746..d317f738 100644 --- a/codes/zig/chapter_dynamic_programming/min_cost_climbing_stairs_dp.zig +++ b/codes/zig/chapter_dynamic_programming/min_cost_climbing_stairs_dp.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 爬楼梯最小代价:动态规划 -fn min_cost_climbing_stairs_dp(comptime cost: []i32) i32 { +fn minCostClimbingStairsDP(comptime cost: []i32) i32 { comptime var n = cost.len - 1; if (n == 1 or n == 2) { return cost[n]; @@ -23,7 +23,7 @@ fn min_cost_climbing_stairs_dp(comptime cost: []i32) i32 { } // 爬楼梯最小代价:状态压缩后的动态规划 -fn min_cost_climbing_stairs_dp_comp(cost: []i32) i32 { +fn minCostClimbingStairsDPComp(cost: []i32) i32 { var n = cost.len - 1; if (n == 1 or n == 2) { return cost[n]; @@ -44,10 +44,10 @@ pub fn main() !void { comptime var cost = [_]i32{ 0, 1, 10, 1, 1, 1, 10, 1, 1, 10, 1 }; std.debug.print("输入楼梯的代价列表为 {any}\n", .{cost}); - var res = min_cost_climbing_stairs_dp(&cost); + var res = minCostClimbingStairsDP(&cost); std.debug.print("输入楼梯的代价列表为 {}\n", .{res}); - res = min_cost_climbing_stairs_dp_comp(&cost); + res = minCostClimbingStairsDPComp(&cost); std.debug.print("输入楼梯的代价列表为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/min_path_sum.zig b/codes/zig/chapter_dynamic_programming/min_path_sum.zig index 4efb35fd..b4afd489 100644 --- a/codes/zig/chapter_dynamic_programming/min_path_sum.zig +++ b/codes/zig/chapter_dynamic_programming/min_path_sum.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 最小路径和:暴力搜索 -fn min_path_sum_dfs(grid: anytype, i: i32, j: i32) i32 { +fn minPathSumDFS(grid: anytype, i: i32, j: i32) i32 { // 若为左上角单元格,则终止搜索 if (i == 0 and j == 0) { return grid[0][0]; @@ -15,14 +15,14 @@ fn min_path_sum_dfs(grid: anytype, i: i32, j: i32) i32 { return std.math.maxInt(i32); } // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价 - var left = min_path_sum_dfs(grid, i - 1, j); - var up = min_path_sum_dfs(grid, i, j - 1); + var left = minPathSumDFS(grid, i - 1, j); + var up = minPathSumDFS(grid, i, j - 1); // 返回从左上角到 (i, j) 的最小路径代价 return @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))]; } // 最小路径和:记忆化搜索 -fn min_path_sum_dfs_mem(grid: anytype, mem: anytype, i: i32, j: i32) i32 { +fn minPathSumDFSMem(grid: anytype, mem: anytype, i: i32, j: i32) i32 { // 若为左上角单元格,则终止搜索 if (i == 0 and j == 0) { return grid[0][0]; @@ -36,8 +36,8 @@ fn min_path_sum_dfs_mem(grid: anytype, mem: anytype, i: i32, j: i32) i32 { return mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))]; } // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价 - var left = min_path_sum_dfs_mem(grid, mem, i - 1, j); - var up = min_path_sum_dfs_mem(grid, mem, i, j - 1); + var left = minPathSumDFSMem(grid, mem, i - 1, j); + var up = minPathSumDFSMem(grid, mem, i, j - 1); // 返回从左上角到 (i, j) 的最小路径代价 // 记录并返回左上角到 (i, j) 的最小路径代价 mem[@as(usize, @intCast(i))][@as(usize, @intCast(j))] = @min(left, up) + grid[@as(usize, @intCast(i))][@as(usize, @intCast(j))]; @@ -45,7 +45,7 @@ fn min_path_sum_dfs_mem(grid: anytype, mem: anytype, i: i32, j: i32) i32 { } // 最小路径和:动态规划 -fn min_path_sum_dp(comptime grid: anytype) i32 { +fn minPathSumDP(comptime grid: anytype) i32 { comptime var n = grid.len; comptime var m = grid[0].len; // 初始化 dp 表 @@ -69,7 +69,7 @@ fn min_path_sum_dp(comptime grid: anytype) i32 { } // 最小路径和:状态压缩后的动态规划 -fn min_path_sum_dp_comp(comptime grid: anytype) i32 { +fn minPathSumDPComp(comptime grid: anytype) i32 { comptime var n = grid.len; comptime var m = grid[0].len; // 初始化 dp 表 @@ -102,20 +102,20 @@ pub fn main() !void { comptime var m = grid[0].len; // 暴力搜索 - var res = min_path_sum_dfs(&grid, n - 1, m - 1); + var res = minPathSumDFS(&grid, n - 1, m - 1); std.debug.print("从左上角到右下角的最小路径和为 {}\n", .{res}); // 记忆化搜索 var mem = [_][m]i32{[_]i32{-1} ** m} ** n; - res = min_path_sum_dfs_mem(&grid, &mem, n - 1, m - 1); + res = minPathSumDFSMem(&grid, &mem, n - 1, m - 1); std.debug.print("从左上角到右下角的最小路径和为 {}\n", .{res}); // 动态规划 - res = min_path_sum_dp(&grid); + res = minPathSumDP(&grid); std.debug.print("从左上角到右下角的最小路径和为 {}\n", .{res}); // 状态压缩后的动态规划 - res = min_path_sum_dp_comp(&grid); + res = minPathSumDPComp(&grid); std.debug.print("从左上角到右下角的最小路径和为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte(); diff --git a/codes/zig/chapter_dynamic_programming/unbounded_knapsack.zig b/codes/zig/chapter_dynamic_programming/unbounded_knapsack.zig index 855d2504..160bbe46 100644 --- a/codes/zig/chapter_dynamic_programming/unbounded_knapsack.zig +++ b/codes/zig/chapter_dynamic_programming/unbounded_knapsack.zig @@ -5,7 +5,7 @@ const std = @import("std"); // 完全背包:动态规划 -fn unbounded_knapsack_dp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { +fn unboundedKnapsackDP(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { comptime var n = wgt.len; // 初始化 dp 表 var dp = [_][cap + 1]i32{[_]i32{0} ** (cap + 1)} ** (n + 1); @@ -25,7 +25,7 @@ fn unbounded_knapsack_dp(comptime wgt: []i32, val: []i32, comptime cap: usize) i } // 完全背包:状态压缩后的动态规划 -fn unbounded_knapsack_dp_comp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { +fn unboundedKnapsackDPComp(comptime wgt: []i32, val: []i32, comptime cap: usize) i32 { comptime var n = wgt.len; // 初始化 dp 表 var dp = [_]i32{0} ** (cap + 1); @@ -51,11 +51,11 @@ pub fn main() !void { comptime var cap = 4; // 动态规划 - var res = unbounded_knapsack_dp(&wgt, &val, cap); + var res = unboundedKnapsackDP(&wgt, &val, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); // 状态压缩后的动态规划 - res = unbounded_knapsack_dp_comp(&wgt, &val, cap); + res = unboundedKnapsackDPComp(&wgt, &val, cap); std.debug.print("不超过背包容量的最大物品价值为 {}\n", .{res}); _ = try std.io.getStdIn().reader().readByte();