さび対 アルゴリズムの問​​題に関するC ++

Rust. Rustbook, , , -.

Rust , , vis-à-vis C/C++. Rust, (, , RAII .) «» C . C++.

Rust C++, , .

: , , Rust. , Rust C++, . Rust C++.

. , , , . , , , . github. . .

Rust


+ Rust « » : , ( , ), gdb. Rust , .

+ , : , , , . , () ( STL C++).

+ ( std::move, ). ( &, C++).

+UTF-8. , (N) , .

+ ( ). , (, Python).

+- Rust , . Rust , . , .

- , ( borrow checker) , ( ). , , borrow checker'.

- Rust , , . C++ Rust .

- Rust . , StackOverflow. . , GUI, wxWidgets, Qt.

Rust



B A. n , n — - B ( A ). .
// return position of the element if found
fn binary_search(vec: &[u32], value: u32) -> Option<usize> {
    let mut l: i32 = 0;
    let mut r: i32 = vec.len() as i32 - 1;
    while  l <= r {
        let i = ((l + r) / 2) as usize;
        if vec[i] == value {
          return Some(i);
        } else if vec[i] > value {
          r = i as i32 - 1;
        } else if vec[i] < value {
          l = i as i32 + 1;
        } 
    }
    None
}


Rust, :
  1. , mut
  2. Rust , . l = i as i32 + 1



: - , . , .

stdin
fn read_line() -> String {
    let mut line = String::new();
    io::stdin().read_line(&mut line).unwrap();
    line.trim().to_string()
}

fn main() {
    // 1. Read the array
    let n: usize = read_line().parse().unwrap();
    let mut a_vec: Vec<u32> = vec![0; n as usize];
    for (i, token) in read_line().split_whitespace().enumerate() {
        a_vec[i] = token.parse().unwrap();    
    }

...


  1. , -, , String::new() .
  2. , , Option, None . unwrap panic!, None.
  3. String::parse , .. .
  4. Rust ( Python). split_whitespace().enumerate() , .


_merge, in place .
fn _merge(left_slice: &mut [u32], right_slice: &mut [u32]) -> u64


Rust unsafe , .. , . Rust ( , , — ). :
fn _merge(vec: &mut [u32], left: usize, mid: usize, right: usize) -> u64



. . , , Rust — , .., , mut , . unsafe . , , .

Node:
// Type of the reference to the node
type Link = Option<Box<Node>>;

// Huffman tree node struct
#[derive(Debug,Eq)]
struct Node {
    freq: u32,
    letter: char,
    left: Link,
    right: Link,
}

impl Ord for Node {
    // reverse order to make Min-Heap
    fn cmp(&self, b: &Self) -> Ordering {
        b.freq.cmp(&self.freq)
    }
}


  1. .
  2. #[derive(Debug,Eq)]. Debug — -. Eq — .
  3. Node / Ord. . , Node Min-.


.
impl Node {
...
    // traverse tree building letter->code `map`
    fn build_map(&self, map: &mut HashMap<char, String>, prefix: String) {
        match self.right {
            Some(ref leaf) => leaf.build_map(map, prefix.clone() + "1"),
            _ => { },
        }
        match self.left {
            Some(ref leaf) => { leaf.build_map(map, prefix + "0"); },
            _ => { map.insert(self.letter, prefix); },
        }
    }
}


  1. , &Some(ref leaf).
  2. match switch C. match , _ => { }.
  3. -? prefix.clone(), .



: . , . : (0 — , 1 — ), , . Rust , , , , . :
fn add_letter(root: &mut Link, letter: char, code: &str) {
    let mut p: &mut Node = root.as_mut().unwrap();
    for c in code.chars() {
        p = match {p} {
            &mut Node {left: Some(ref mut node), ..} if c == '0' => {
                node
            },
            &mut Node {left: ref mut opt @ None, ..} if c == '0' => {
                *opt = Node::root();
                opt.as_mut().unwrap()
            },
            &mut Node {right: Some(ref mut node), ..} if c == '1' => {
                node
            },
            &mut Node {right: ref mut opt @ None, ..} if c == '1' => {
                *opt = Node::root();
                opt.as_mut().unwrap()
            },
            _ => { panic!("error"); }
        }
    }
    p.letter = letter;
}


  1. match p. &mut Node {left: Some(ref mut node), ..} if c == '0' « p Node , left node c '0'».
  2. Rust , panic!("...") ( ).



— - , . :
fn get_levenshtein_distance(str1: &str, str2: &str) -> u32 {
    let n = str1.len() + 1;
    let m = str2.len() + 1;
    // compute 2D indexes into flat 1D index
    let ind = |i, j| i * m + j;
    let mut vec_d: Vec<u32> = vec![0; n * m];
    for i in 0..n {
        vec_d[ind(i, 0)] = i as u32;
    }
    for j in 0..m {
        vec_d[ind(0, j)] = j as u32;
    }

    for (i, c1) in str1.chars().enumerate() {
        for (j, c2) in str2.chars().enumerate() {
            let c =  if c1 == c2 {0} else {1};
            vec_d[ind(i + 1, j + 1)] = min( min( vec_d[ind(i, j + 1)] + 1
                                               , vec_d[ind(i + 1, j)] + 1
                                               )
                                          , vec_d[ind(i, j)] + c
                                          );
        }
    }
  return vec_d[ind(n - 1, m - 1)];
}


  1. str1: &str — . , , std::string_view C++17.
  2. let ind = |i, j| i * m + j; — .


Rust vs C++


, , , . Intel Core i7-4770, 16GB DDR3, SSD, Linux Mint 18.1 64-bit. :
[>] rustc --version
rustc 1.22.1 (* 2017-11-22)
[>] g++ -v
...
gcc version 7.2.0



:
  1. , , /dev/null
  2. * (core) ( /)
  3. 10 ,
  4. , , , . .
  5. , C++ - / iostream. . , std::sync_with_stdio(false)
  6. , Rust Huffman encoding HashMap
  7. Rust , C++. , .
  8. , Rust 10%, , , .



, , , Rust C++. , , , .

, github: https://github.com/dmitryikh/rust-vs-cpp-bench.

, !

11.12.2017


!
:
  1. binary_search. Option
  2. Binary_search A, A
  3. -DNDEBUG C++. ..
  4. Huffman_decoding, - C++ . .
  5. , - .


. , ±10% .


Source: https://habr.com/ru/post/J344282/


All Articles