Skip to content
On this page

实用工具

1、file

1.1、获取文件路径

三方库

  • dirs: 获取用户目录
js
use std::path;
use dirs::home_dir;

fn get_file_path() -> path::PathBuf {
  home_dir().unwrap_or_default().join("path.txt")
}

1.2、判断文件是否存在

js
use std::{fs};

fn file_exist() -> bool {
  let dir = get_file_path();
  fs::metadata(dir).is_ok()
}

1.3、创建文件

js
use std::{fs, io};

fn create_file() -> io::Result<()> {
  let dir = get_file_path();
  fs::File::create(dir)?;
  Ok(())
}

1.4、文件不存在就创建

js
fn check_db_file() -> io::Result<()> {
    if !db_exists() {
        create_db_file()?;
    }
    Ok(())
}

1.5、删除文件

js
fn delete_file() -> io::Result<()> {
    let dir = get_file_path();
    fs::remove_file(dir)?;
    Ok(())
}

1.6、删除目录

js
fn delete_dir() -> io::Result<()> {
    let dir = get_file_path();
    fs::remove_dir(dir)?;
    Ok(())
}

1.7、传统方式检测文件

js
let mut file = fs::File::open("path.txt").unwrap_or_else(| error | {
  if error.kind() == io::ErrorKind::NotFound {
    fs::File::create("path.txt").unwrap_or_else(| error | {
      panic!("{:?}", error)
    });
    fs::File::open("path.txt").unwrap()
  } else {
    panic!("{:?}", error)
  }
});
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
println!("{}", content);

1.8、读取文件

js
fn read_file() -> Result<String, io::Error> {
  let mut s = String::new();
  fs::File::open("path.txt")?.read_to_string(&mut s)?;
  Ok(s)
}

2、Error

2.1、任意错误类型

js
fn main() -> Result<(), Box<dyn error::Error>>{
  fs::File::open("path.txt")?;
  Ok(())
}

3、最大值查找

3.1、数字比较

js
fn largest(list: &[i32]) -> i32 {
  let mut largest = list[0];
  for &item in list {
    if item > largest {
      largest = item;
    }
  }
  largest
}

3.2、数字比较2

js
fn largest2(list: &[i32]) -> i32 {
  let mut largest = list[0];
  for item in list {
    if *item > largest {
      largest = *item;
    }
  }
  largest
}

3.3、通用写法

js
fn largest3<T: PartialOrd + Clone>(list: &[T]) -> &T {
  let mut largest = &list[0];
  for item in list {
    if item > largest {
      largest = item;
    }
  }
  largest
}

let str = vec![1, 2, 3];
let result = largest3(&str);
println!("{}", result);

4、算法

4.1、冒泡排序

js
fn bubble_sort<T: Ord>(arr: &mut [T]) {
    for i in 0..arr.len() {
        for j in 0..arr.len() - 1 - i {
            if arr[j] > arr[j + 1] {
                arr.swap(j, j + 1);
            }
        }
    }
}

#[test]
fn test_bubble() {
  let mut arr = vec![2,3,1,5,4];
  bubble_sort(&mut arr);
  println!("{:?}", arr);
  for i in 0..arr.len() - 1 {
      assert!(arr[i] <= arr[i+1]);
  }
}

4.2、选择排序

js
fn select_sort<T: Ord>(arr: &mut [T]) {
  let len = arr.len();
  for left_index in 0..len {
    let mut smallest_index = left_index;
    for right_index in (left_index + 1)..len {
      if arr[right_index] < arr[smallest_index] {
        smallest_index = right_index;
      }
    }
    arr.swap(smallest_index, left_index);
  }
}

fn main() {
  let mut arr = vec![2,3,1,5,4];
  select_sort(&mut arr);
  println!("{:?}", arr);
}

4.3、插入排序

js
fn insert_sort<T>(arr: &[T]) -> Vec<T>
where T: Ord + Clone {
  let mut res: Vec<T> = Vec::with_capacity(arr.len());
  for item in arr.iter().cloned() {
      let n_len = res.len();
      for i in 0..=n_len {
        if i == n_len || res[i] > item {
          res.insert(i, item);
          break;
        }
      }
  }
  res
}

fn main() {
  let mut arr = vec![2,3,1,5,4];
  arr = insert_sort(&arr);
  println!("{:?}", arr);
}

4.4、归并排序

js
fn merge_sort<T>(mut v: Vec<T>) -> Vec<T> where T: Ord {
  if v.len() <= 1 {
    return v;
  }
  let mut res = Vec::with_capacity(v.len());
  let b = v.split_off(v.len() / 2);
  let a = merge_sort(v);
  let b = merge_sort(b);

  let mut a_it = a.into_iter();
  let mut b_it = b.into_iter();
  let mut a_peek = a_it.next();
  let mut b_peek = b_it.next();
  loop {
      match a_peek {
          Some(ref a_val) => match b_peek { // a有值 b有值
              Some(ref b_val) => {
                  if b_val < a_val {
                      res.push(b_peek.take().unwrap());
                      b_peek = b_it.next();
                  } else {
                      res.push(a_peek.take().unwrap());
                      a_peek = a_it.next();
                  }
              }
              None => {
                  res.push(a_peek.take().unwrap());
                  res.extend(a_it);
                  return res;
              }
          }
          None => {
            if let Some(b_val) = b_peek {
                res.push(b_val);
            }
            res.extend(b_it);
            return res;
          }
      }
  }
}

#[cfg(test)]
mod tests {
    use super::merge_sort;

    #[test]
    fn it_works() {
        let arr = vec![4, 1, 3, 5, 23];
        assert_eq!(merge_sort(arr), vec![1, 3, 4, 5, 23]);
    }
}

4.5、快速排序

js
// 从小大到大排序, 找到中间值
fn pivot<T: Ord>(v: &mut [T]) -> usize {
  let mut p = 0;
  for i in 1..v.len() {
    if v[i] < v[p] {
      // p+1与i交换
      v.swap(p+1, i);
      // p与p+1交换
      v.swap(p, p+1);
      // p++
      p += 1;
    }
  }
  p
}

fn quick_sort<T: Ord>(v: &mut [T]) {
  if v.len() <= 1 {
    return;
  }
  let p = pivot(v);
  let (a, b) = v.split_at_mut(p);
  quick_sort(a);
  quick_sort(&mut b[1..]);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_pivot() {
      let mut arr = vec![4, 1, 3, 5, 23];
      let p = pivot(&mut arr);
      for i in arr {
          println!("{}--{}", i, p);
      }
      assert_eq!(vec![1, 3, 4, 5, 23], vec![1, 3, 4, 5, 23]);
    }

    #[test]
    fn test_quick() {
      let mut arr = vec![4, 1, 3, 5, 23];
      quick_sort(&mut arr);
      for i in arr {
          println!("{}", i);
      }
      assert_eq!(vec![1, 3, 4, 5, 23], vec![1, 3, 4, 5, 23]);
    }
}

写法2

js
fn main() {
   let mut list = vec![122, 21, 3,2,1222];
   quick_sort(&mut list);
   println!("{:?}", list);
}

fn quick_sort<T: Ord + Copy>(list: &mut [T]) {
  quick_sort_part(list, 0, list.len());
}

fn quick_sort_part<T: Ord + Copy>(list: &mut [T], start: usize, end: usize) {
  if start < end {
    let mid = quick_partition(list, start, end);
    quick_sort_part(list, start, mid);
    quick_sort_part(list, mid+1, end);
  }
}

fn quick_partition<T: Ord + Copy>(list: &mut [T], start: usize, end: usize) -> usize {
    let p_val = list[start];
    let mut j = end;
    for i in (start+1..end).rev() {
        if list[i] > p_val {
            j -= 1;
            list.swap(i, j);
        }
    }
    list.swap(start, j-1);
    j-1
}

Released under the MIT License.