zig : update codes style && rust : add codes for chapter_backtracking. (#613)
* zig : update codes style * rust : add codes for chapter_backtracking * zig : update codes style
This commit is contained in:
parent
51a4c5089e
commit
ead33ca863
@ -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"
|
@ -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<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {
|
||||
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);
|
||||
}
|
@ -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<Vec<Rc<RefCell<TreeNode>>>>, path: &mut Vec<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {
|
||||
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);
|
||||
}
|
||||
}
|
@ -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<Vec<Rc<RefCell<TreeNode>>>>, path: &mut Vec<Rc<RefCell<TreeNode>>>, root: Option<Rc<RefCell<TreeNode>>>) {
|
||||
// 剪枝
|
||||
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);
|
||||
}
|
||||
}
|
@ -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<Rc<RefCell<TreeNode>>>) -> bool {
|
||||
return !state.is_empty() && state.get(state.len() - 1).unwrap().borrow().val == 7;
|
||||
}
|
||||
|
||||
/* 记录解 */
|
||||
fn record_solution(state: &mut Vec<Rc<RefCell<TreeNode>>>, res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>) {
|
||||
res.push(state.clone());
|
||||
}
|
||||
|
||||
/* 判断在当前状态下,该选择是否合法 */
|
||||
fn is_valid(_: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) -> bool {
|
||||
return choice.borrow().val != 3;
|
||||
}
|
||||
|
||||
/* 更新状态 */
|
||||
fn make_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, choice: Rc<RefCell<TreeNode>>) {
|
||||
state.push(choice);
|
||||
}
|
||||
|
||||
/* 恢复状态 */
|
||||
fn undo_choice(state: &mut Vec<Rc<RefCell<TreeNode>>>, _: Rc<RefCell<TreeNode>>) {
|
||||
state.remove(state.len() - 1);
|
||||
}
|
||||
|
||||
/* 回溯算法:例题三 */
|
||||
fn backtrack(state: &mut Vec<Rc<RefCell<TreeNode>>>, choices: &mut Vec<Rc<RefCell<TreeNode>>>, res: &mut Vec<Vec<Rc<RefCell<TreeNode>>>>) {
|
||||
// 检查是否为解
|
||||
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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user