TL;DR
rustで学んだことのメモ
String -> Vec
String使ってるとindexで操作できないので、charのベクトルにする必要がある
let vec: Vec<char> = string.chars().collect();
vec![1, 2, 3] -> "123"
let vec: Vec<usize> = vec![1, 2, 3]
let str_num: String = vec.iter().map(|x| std::char::from_digit(*x as u32, 10).unwrap()).collect();
&x -> x
参照を外す
*x
sumなどの処理をベクターに対して使う
vecのままじゃ使えないのでイテレーターに変更する
let sum = vec.iter().sum();
二項係数の計算
fn init_nCk(n: usize, size: usize, MOD: usize) -> Vec<usize> {
let mut fact_inv: Vec<usize> = Vec::new();
let mut inv: Vec<usize> = Vec::new();
let mut com: Vec<usize> = Vec::new();
fact_inv.resize(size, 0);
inv.resize(size, 0);
com.resize(size, 0);
fact_inv[0] = 1;
fact_inv[1] = 1;
inv[1] = 1;
com[0] = 1;
for i in 2..size {
inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
fact_inv[i] = fact_inv[i - 1] * inv[i] % MOD;
}
for i in 1..size {
com[i] = com[i - 1] * ((n - i + 1) * inv[i] % MOD) % MOD;
}
com
}
fn nCk(k: usize, com: Vec<usize> {
com[k]
}
Vec -> VecDeque
Vecだとfrontを取ってくる操作が遅いので、VecDequeを使う
use std::collections::VecDeque;
let vec_deque = VecDeque::from(vec)
pop_front
とpop_back
が使えるが、Optionで包まれて返ってくるので、unwrapが必要なことに注意。
HashMap
defaultdict
entry -> or_insertを使う。
use std::collections::HashMap;
let mut map: HashMap<usize, usize> = HashMap::new();
map.entry(1).or_insert(0);
keyの順序付きHashMap
std::collections::BTreeMap
を使う。
valueでソートのやり方が知りたい
HashSet
集合演算
use std::collections::HashSet;
// 差集合
let diff: HashSet<_> = set_a.difference(set_b).collect();
// 対称差集合
let diff: HashSet<_> = set_a.symmetric_difference(set_b).collect();
format
000 001 002 ... 999
みたいなのを作るときとかに使うやつ
(0..=999).map(|x| format!("{:03}", x))
enumerate
みんな大好きenumerate
for (i, x) in vec.iter().enumerate(){
todo!();
}
整数かどうかの判定
なんかlogとった値が整数になるかの判定みたいなことがしたかった
num
クレートを使えばできる
extern crate num;
let logged = 4.0.log2();
let flag = num::rational::Ratio::from_float(logged).unwrap().is_integer();
みたいな感じ
全探索
DFS
再帰ができなくて泣いていた。
structを作ってメソッド実装するとよいらしい [参考 static mutの危険性]。
あとイテレーター回すところでcloneしてからにしないと所有権で死ぬ。
struct Graph {
graph: HashMap<usize, Vec<usize>>,
seen: Vec<bool>
}
impl Graph {
fn dfs(&mut self, start: usize) {
self.seen[start] = true;
for next_start in self.graph.clone().get(&start).unwrap() {
if !self.seen[*next_start] {
self.dfs(*next_start)
}
}
}
}