Implement merge sort that counts inversions
This commit is contained in:
parent
60dfe69601
commit
d845ce64a4
71
src/main.rs
71
src/main.rs
@ -1,57 +1,32 @@
|
|||||||
use std::clone::Clone;
|
mod merge_sort;
|
||||||
use std::cmp::PartialOrd;
|
use crate::merge_sort::merge_sort_inversions;
|
||||||
use std::marker::Copy;
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
use std::io::{BufRead, BufReader, Error, ErrorKind};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
fn merge<T: Clone + PartialOrd + Copy>(a: Vec<T>, b: Vec<T>) -> Vec<T> {
|
fn read_to_vector(path: &str) -> Result<Vec<i64>, io::Error> {
|
||||||
let mut r = vec![];
|
let file = File::open(path)?;
|
||||||
let mut i = 0;
|
let br = BufReader::new(file);
|
||||||
let mut j = 0;
|
let mut v = Vec::new();
|
||||||
|
for line in br.lines() {
|
||||||
while i < a.len() && j < b.len() {
|
let line = line?;
|
||||||
if a[i] < b[j] {
|
let n = line
|
||||||
r.push(a[i]);
|
.trim()
|
||||||
i += 1;
|
.parse()
|
||||||
} else {
|
.map_err(|e| Error::new(ErrorKind::InvalidData, e))?;
|
||||||
r.push(b[j]);
|
v.push(n);
|
||||||
j += 1;
|
|
||||||
}
|
}
|
||||||
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
while i < a.len() {
|
fn c1a2() {
|
||||||
r.push(a[i]);
|
let vec = read_to_vector("data/week_2_assignment_2.txt").unwrap();
|
||||||
i += 1;
|
let (_sorted, inversions) = merge_sort_inversions(vec);
|
||||||
}
|
// println!("{:?}", sorted.len());
|
||||||
|
println!("course 1 assignment 2: {:?}", inversions);
|
||||||
while j < b.len() {
|
|
||||||
r.push(b[j]);
|
|
||||||
j += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn merge_sort<T: Clone + PartialOrd + Copy>(v: Vec<T>) -> Vec<T> {
|
|
||||||
if v.len() <= 1 {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
let i = v.len() / 2;
|
|
||||||
let a = merge_sort((&v[..i]).to_vec());
|
|
||||||
let b = merge_sort((&v[i..]).to_vec());
|
|
||||||
let r = merge(a, b);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mult_bin(a: i64, b: i64) -> i64 {
|
|
||||||
return a * b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
c1a2();
|
||||||
let l = vec![4, 2, 1, 3];
|
|
||||||
let l = merge_sort(l);
|
|
||||||
println!("{:?}", l);
|
|
||||||
|
|
||||||
let r = mult_bin(42, 21);
|
|
||||||
println!("{:?}", r);
|
|
||||||
}
|
}
|
||||||
|
48
src/merge_sort.rs
Normal file
48
src/merge_sort.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use std::clone::Clone;
|
||||||
|
use std::cmp::PartialOrd;
|
||||||
|
|
||||||
|
fn merge_count_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
|
||||||
|
a: Vec<T>,
|
||||||
|
b: Vec<T>,
|
||||||
|
) -> (Vec<T>, usize) {
|
||||||
|
let mut r = vec![];
|
||||||
|
let mut i = 0;
|
||||||
|
let mut j = 0;
|
||||||
|
let mut inversions = 0;
|
||||||
|
|
||||||
|
while i < a.len() && j < b.len() {
|
||||||
|
if a[i] < b[j] {
|
||||||
|
r.push(a[i]);
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
r.push(b[j]);
|
||||||
|
j += 1;
|
||||||
|
inversions += a.len() - i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while i < a.len() {
|
||||||
|
r.push(a[i]);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while j < b.len() {
|
||||||
|
r.push(b[j]);
|
||||||
|
j += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (r, inversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn merge_sort_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
|
||||||
|
v: Vec<T>,
|
||||||
|
) -> (Vec<T>, usize) {
|
||||||
|
if v.len() <= 1 {
|
||||||
|
return (v, 0);
|
||||||
|
}
|
||||||
|
let i = v.len() / 2;
|
||||||
|
let (a, n) = merge_sort_inversions((&v[..i]).to_vec());
|
||||||
|
let (b, m) = merge_sort_inversions((&v[i..]).to_vec());
|
||||||
|
let (r, p) = merge_count_inversions(a, b);
|
||||||
|
return (r, n + m + p);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user