学习 Rust cookbook 之算法篇(algorithm)
学习 Rust cookbook 之算法篇(algorithm)
前言
一直以来,我都沉迷于如何学好 Rust 而无法自拔,以至于“想”的时间比“做”的时间还多。chrome 上日积月累的 tab 数量,是我愈发的焦躁,当我尝试从其中一个 tab 下手时,god ,有点看不懂,我对 Rust 语法还知之甚少,于是还是无法“学习掉”那个 tab。下意识的翻到页面底部,又发现另一篇 Rust 博文,嗯!看起来很有技术含量,想学,mark 一下。。。
很不幸的,当我决定从众多 tab 中选一个来进行“消化”时,我找到了这个 Rust cookbook,它包含了 算法、命令行、数据压缩、并发、数据加密、日期和时间、编解码、错误处理、文件系统、硬件支持、内存管理、网络、操作系统、统计学、文本处理、web 服务等章节,当你学习了《Rust 编程语言》一书后,可以从更加实用的角度来学习这本 cookbook
algorithm 篇简介
第一节算法篇,主要包含生成随机数、数组排序等内容,请注意,学习这篇 Rust 笔记之前,请一定要阅读完《Rust 编程语言》。之后,再与我一同学习 Rust cookbook。
实战
教程中,教我们使用 rand::thread_rng
的 rand::Rng
方法生成随机数。每个线程都会初始化一个随机数生成器。如果是获取整数,则整数是在其类型内均匀分布的,如果是浮点数,则是在 0 和 1 但不包含 1 之前均匀分布的。接下来,编写代码
首先新建可运行的项目:
cargo new --bin cookbook
cd cookbook
在 main.rs 同级目录下新建 algorithm.rs
文件,我们采用每一章一个 mod (一个文件)的方式,写示例程序。文件目录结构如下:
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── algorithm.rs
│ └── main.rs
└── target
在 dependencies 下加入 rand
crate 依赖,Cargo.toml 内容如下:
[package]
name = "cookbook"
version = "0.1.0"
authors = ["suhanyujie <suhanyujie@qq.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.7.3"
生成指定类型的随机数
此时命令行下运行 cargo test
时,会自动下载 rand
crate 内容。接下来,可以根据 rand crate 官方文档示例,在 algorithm.rs 文件中编写一个生成一个类型为 u8
的随机数:
extern crate rand;
use rand::Rng;
pub fn gen_a_u8_num() -> u8 {
let mut rng = rand::thread_rng();
let n1: u8 = rng.gen();
return n1;
}
在 main.rs 文件中进行调用该函数:
mod algorithm;
use algorithm::*;
fn main() {
let n1 = gen_a_u8_num();
println!("Rand num of u8 is:{}", n1);
}
代码写好了,运行一下试试 cargo run
,执行成功,在终端会打印出形如 Rand num of u8 is:135
的一句话。我将源码放到了 Github 的仓库中,点击可以查看。
生成指定范围的随机数
- 在平时的业务代码中,直接获取一个随机数的场景还是比较少的,大都是以下场景:
- 在给定的一个数组中,随机获取其中的一个
- 获取指定范围内的随机数
- 这里我们先探讨以下如何用 Rust 生成指定范围内的随机数。rand crate 中提供了这样的 api,通过
Rng::gen_range
获取一个半开区间范围的随机值,使用方式如下:
let mut rng = rand::thread_rng();
let num = rng.gen_range(0, 100);
- 通过这种方式,即可获取一个从 0 到 100,但不包括 100 的随机数。简单地封装成 函数:
pub fn gen_random_within_range(min: isize, max: isize) -> isize {
let mut rng = rand::thread_rng();
let num = rng.gen_range(min, max);
return num as isize;
}
- 使用命令
cargo run
即可编译通过并运行。 - 在 PHP 中,标准库函数自带了
rand
用于生成指定范围内的随机数,不仅如此,还有一个比rand
更好的方式生成随机数mt_rand
。Rust 的 rand crate 中也提供了一个比上面 gen_range 的方式更好的生成随机数方式Uniform
。因此我们也尝试一下编写 Rust 版本的 mt_rand:
/// 用更好的方式生成指定范围内的随机数
pub fn mt_rand(min: isize, max: isize) ->isize {
let mut rng = rand::thread_rng();
let die = Uniform::from(min..max);
let num = die.sample(&mut rng);
num as isize
}
- 使用命令
cargo run
即可编译通过并运行。