use std::cmp::Ordering::Equal;
use std::ops::Add;
struct SortedVecsIter<T> {
vec1: Vec<T>,
vec2: Vec<T>,
}
impl<T> SortedVecsIter<T> {
fn len(&self) -> usize {
self.vec1.len() + self.vec2.len()
}
}
impl<T: PartialOrd> Iterator for SortedVecsIter<T> {
type Item = T;
fn next(&mut self) -> Option<T> {
match (self.vec1.last(), self.vec2.last()) {
(Some(n1), Some(n2)) if n1 >= n2 => self.vec1.pop(),
(Some(_), Some(_)) => self.vec2.pop(),
(Some(_), _) => self.vec1.pop(),
(_, Some(_)) => self.vec2.pop(),
_ => None,
}
}
}
pub fn median_sorted_two_vecs<T>(nums1: Vec<T>, nums2: Vec<T>) -> f64
where
T: PartialOrd + Add + Into<f64>,
f64: From<<T as Add>::Output>,
{
let mut vecs_iter = SortedVecsIter {
vec1: nums1,
vec2: nums2,
};
let length = vecs_iter.len();
let middle = length / 2;
if 0 == length % 2 {
let mut halves = vecs_iter.skip(middle - 1);
let first: f64 = halves.next().unwrap().into();
let second: f64 = halves.next().unwrap().into();
(first + second) / 2.0
} else {
vecs_iter.nth(middle).unwrap().into()
}
}
pub fn median_unsorted_two_vecs<T>(nums1: &mut Vec<T>, nums2: &mut Vec<T>) -> f64
where
T: PartialOrd + Add + Copy + Into<f64>,
f64: From<<T as Add>::Output>,
{
nums1.append(nums2);
nums1.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Equal));
let mut median: f64;
let midpoint = nums1.len() / 2;
if nums1.len() % 2 == 0 {
median = (nums1[midpoint - 1] + nums1[midpoint]).into();
median /= 2.0;
} else {
median = nums1[midpoint].into();
}
median
}
#[test]
fn test_unsorted_i32() {
let mut nums1 = vec![5, 1, 7];
let mut nums2 = vec![7, 1, 4];
assert_eq!(median_unsorted_two_vecs(&mut nums1, &mut nums2), 4.5);
}
#[test]
fn test_unsorted_f64() {
let mut nums1 = vec![5.6, 1.5, 7.5];
let mut nums2 = vec![7.5, 1.5, 4.5];
assert_eq!(median_unsorted_two_vecs(&mut nums1, &mut nums2), 5.05);
}
#[test]
fn test_sorted() {
let nums1 = vec![1, 5, 7];
let nums2 = vec![1, 4, 7];
assert_eq!(median_sorted_two_vecs(nums1, nums2), 4.5);
}
#[test]
fn test_sorted_f64() {
let nums1 = vec![1.25, 15.2, 50.47];
let nums2 = vec![0.25, 15.77, 200.6];
assert_eq!(median_sorted_two_vecs(nums1, nums2), 15.485);
}