mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	feat: add rust codes for chapter greedy (#646)
* feat: add rust codes for chapter greedy * Update max_product_cutting.rs --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
		@ -349,5 +349,25 @@ path = "chapter_divide_and_conquer/hanota.rs"
 | 
				
			|||||||
name = "build_tree"
 | 
					name = "build_tree"
 | 
				
			||||||
path = "chapter_divide_and_conquer/build_tree.rs"
 | 
					path = "chapter_divide_and_conquer/build_tree.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run Command: cargo run --bin coin_change_greedy
 | 
				
			||||||
 | 
					[[bin]]
 | 
				
			||||||
 | 
					name = "coin_change_greedy"
 | 
				
			||||||
 | 
					path = "chapter_greedy/coin_change_greedy.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run Command: cargo run --bin fractional_knapsack
 | 
				
			||||||
 | 
					[[bin]]
 | 
				
			||||||
 | 
					name = "fractional_knapsack"
 | 
				
			||||||
 | 
					path = "chapter_greedy/fractional_knapsack.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run Command: cargo run --bin max_capacity
 | 
				
			||||||
 | 
					[[bin]]
 | 
				
			||||||
 | 
					name = "max_capacity"
 | 
				
			||||||
 | 
					path = "chapter_greedy/max_capacity.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run Command: cargo run --bin max_product_cutting
 | 
				
			||||||
 | 
					[[bin]]
 | 
				
			||||||
 | 
					name = "max_product_cutting"
 | 
				
			||||||
 | 
					path = "chapter_greedy/max_product_cutting.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
rand = "0.8.5"
 | 
					rand = "0.8.5"
 | 
				
			||||||
							
								
								
									
										54
									
								
								codes/rust/chapter_greedy/coin_change_greedy.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								codes/rust/chapter_greedy/coin_change_greedy.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * File: coin_change_greedy.rs
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-22
 | 
				
			||||||
 | 
					 * Author: night-cruise (2586447362@qq.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 零钱兑换:贪心 */
 | 
				
			||||||
 | 
					fn coin_change_greedy(coins: &[i32], mut amt: i32) -> i32 {
 | 
				
			||||||
 | 
					    // 假设 coins 列表有序
 | 
				
			||||||
 | 
					    let mut i = coins.len() - 1;
 | 
				
			||||||
 | 
					    let mut count = 0;
 | 
				
			||||||
 | 
					    // 循环进行贪心选择,直到无剩余金额
 | 
				
			||||||
 | 
					    while amt > 0 {
 | 
				
			||||||
 | 
					        // 找到小于且最接近剩余金额的硬币
 | 
				
			||||||
 | 
					        while coins[i] > amt {
 | 
				
			||||||
 | 
					            i -= 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 选择 coins[i]
 | 
				
			||||||
 | 
					        amt -= coins[i];
 | 
				
			||||||
 | 
					        count += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 若未找到可行方案,则返回 -1
 | 
				
			||||||
 | 
					    if amt == 0 {
 | 
				
			||||||
 | 
					        count
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        -1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    // 贪心:能够保证找到全局最优解
 | 
				
			||||||
 | 
					    let coins = [1, 5, 10, 20, 50, 100];
 | 
				
			||||||
 | 
					    let amt = 186;
 | 
				
			||||||
 | 
					    let res = coin_change_greedy(&coins, amt);
 | 
				
			||||||
 | 
					    println!("\ncoins = {:?}, amt = {}", coins, amt);
 | 
				
			||||||
 | 
					    println!("凑到 {} 所需的最少硬币数量为 {}", amt, res);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心:无法保证找到全局最优解
 | 
				
			||||||
 | 
					    let coins = [1, 20, 50];
 | 
				
			||||||
 | 
					    let amt = 60;
 | 
				
			||||||
 | 
					    let res = coin_change_greedy(&coins, amt);
 | 
				
			||||||
 | 
					    println!("\ncoins = {:?}, amt = {}", coins, amt);
 | 
				
			||||||
 | 
					    println!("凑到 {} 所需的最少硬币数量为 {}", amt, res);
 | 
				
			||||||
 | 
					    println!("实际上需要的最少数量为 3 ,即 20 + 20 + 20");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心:无法保证找到全局最优解
 | 
				
			||||||
 | 
					    let coins = [1, 49, 50];
 | 
				
			||||||
 | 
					    let amt = 98;
 | 
				
			||||||
 | 
					    let res = coin_change_greedy(&coins, amt);
 | 
				
			||||||
 | 
					    println!("\ncoins = {:?}, amt = {}", coins, amt);
 | 
				
			||||||
 | 
					    println!("凑到 {} 所需的最少硬币数量为 {}", amt, res);
 | 
				
			||||||
 | 
					    println!("实际上需要的最少数量为 2 ,即 49 + 49");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								codes/rust/chapter_greedy/fractional_knapsack.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								codes/rust/chapter_greedy/fractional_knapsack.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * File: coin_change_greedy.rs
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-22
 | 
				
			||||||
 | 
					 * Author: night-cruise (2586447362@qq.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 物品 */
 | 
				
			||||||
 | 
					struct Item {
 | 
				
			||||||
 | 
					    w: i32, // 物品重量
 | 
				
			||||||
 | 
					    v: i32, // 物品价值
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Item {
 | 
				
			||||||
 | 
					    fn new(w: i32, v: i32) -> Self {
 | 
				
			||||||
 | 
					        Self { w, v }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 分数背包:贪心 */
 | 
				
			||||||
 | 
					fn fractional_knapsack(wgt: &[i32], val: &[i32], mut cap: i32) -> f64 {
 | 
				
			||||||
 | 
					    // 创建物品列表,包含两个属性:重量、价值
 | 
				
			||||||
 | 
					    let mut items = wgt
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .zip(val.iter())
 | 
				
			||||||
 | 
					        .map(|(&w, &v)| Item::new(w, v))
 | 
				
			||||||
 | 
					        .collect::<Vec<Item>>();
 | 
				
			||||||
 | 
					    // 按照单位价值 item.v / item.w 从高到低进行排序
 | 
				
			||||||
 | 
					    items.sort_by(|a, b| {
 | 
				
			||||||
 | 
					        (b.v as f64 / b.w as f64)
 | 
				
			||||||
 | 
					            .partial_cmp(&(a.v as f64 / a.w as f64))
 | 
				
			||||||
 | 
					            .unwrap()
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    // 循环贪心选择
 | 
				
			||||||
 | 
					    let mut res = 0.0;
 | 
				
			||||||
 | 
					    for item in &items {
 | 
				
			||||||
 | 
					        if item.w <= cap {
 | 
				
			||||||
 | 
					            // 若剩余容量充足,则将当前物品整个装进背包
 | 
				
			||||||
 | 
					            res += item.v as f64;
 | 
				
			||||||
 | 
					            cap -= item.w;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // 若剩余容量不足,则将当前物品的一部分装进背包
 | 
				
			||||||
 | 
					            res += item.v as f64 / item.w as f64 * cap as f64;
 | 
				
			||||||
 | 
					            // 已无剩余容量,因此跳出循环
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let wgt = [10, 20, 30, 40, 50];
 | 
				
			||||||
 | 
					    let val = [50, 120, 150, 210, 240];
 | 
				
			||||||
 | 
					    let cap = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心算法
 | 
				
			||||||
 | 
					    let res = fractional_knapsack(&wgt, &val, cap);
 | 
				
			||||||
 | 
					    println!("不超过背包容量的最大物品价值为 {}", res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								codes/rust/chapter_greedy/max_capacity.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								codes/rust/chapter_greedy/max_capacity.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * File: coin_change_greedy.rs
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-22
 | 
				
			||||||
 | 
					 * Author: night-cruise (2586447362@qq.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 最大容量:贪心 */
 | 
				
			||||||
 | 
					fn max_capacity(ht: &[i32]) -> i32 {
 | 
				
			||||||
 | 
					    // 初始化 i, j 分列数组两端
 | 
				
			||||||
 | 
					    let mut i = 0;
 | 
				
			||||||
 | 
					    let mut j = ht.len() - 1;
 | 
				
			||||||
 | 
					    // 初始最大容量为 0
 | 
				
			||||||
 | 
					    let mut res = 0;
 | 
				
			||||||
 | 
					    // 循环贪心选择,直至两板相遇
 | 
				
			||||||
 | 
					    while i < j {
 | 
				
			||||||
 | 
					        // 更新最大容量
 | 
				
			||||||
 | 
					        let cap = std::cmp::min(ht[i], ht[j]) * (j - i) as i32;
 | 
				
			||||||
 | 
					        res = std::cmp::max(res, cap);
 | 
				
			||||||
 | 
					        // 向内移动短板
 | 
				
			||||||
 | 
					        if ht[i] < ht[j] {
 | 
				
			||||||
 | 
					            i += 1;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            j -= 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let ht = [3, 8, 5, 2, 7, 7, 3, 4];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心算法
 | 
				
			||||||
 | 
					    let res = max_capacity(&ht);
 | 
				
			||||||
 | 
					    println!("最大容量为 {}", res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								codes/rust/chapter_greedy/max_product_cutting.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								codes/rust/chapter_greedy/max_product_cutting.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * File: coin_change_greedy.rs
 | 
				
			||||||
 | 
					 * Created Time: 2023-07-22
 | 
				
			||||||
 | 
					 * Author: night-cruise (2586447362@qq.com)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 最大切分乘积:贪心 */
 | 
				
			||||||
 | 
					fn max_product_cutting(n: i32) -> i32 {
 | 
				
			||||||
 | 
					    // 当 n <= 3 时,必须切分出一个 1
 | 
				
			||||||
 | 
					    if n <= 3 {
 | 
				
			||||||
 | 
					        return 1 * (n - 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // 贪心地切分出 3 ,a 为 3 的个数,b 为余数
 | 
				
			||||||
 | 
					    let a = n / 3;
 | 
				
			||||||
 | 
					    let b = n % 3;
 | 
				
			||||||
 | 
					    if b == 1 {
 | 
				
			||||||
 | 
					        // 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
 | 
				
			||||||
 | 
					        3_i32.pow(a as u32 - 1) * 2 * 2
 | 
				
			||||||
 | 
					    } else if b == 2 {
 | 
				
			||||||
 | 
					        // 当余数为 2 时,不做处理
 | 
				
			||||||
 | 
					        3_i32.pow(a as u32) * 2
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // 当余数为 0 时,不做处理
 | 
				
			||||||
 | 
					        3_i32.pow(a as u32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Driver Code */
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let n = 58;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 贪心算法
 | 
				
			||||||
 | 
					    let res = max_product_cutting(n);
 | 
				
			||||||
 | 
					    println!("最大切分乘积为 {}", res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user