mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 14:52:41 +00:00
uucore/ranges: refactor and test complement
This commit is contained in:
parent
7890228f82
commit
003b483705
1 changed files with 43 additions and 46 deletions
|
@ -81,11 +81,11 @@ impl Range {
|
||||||
ranges.push(range_item);
|
ranges.push(range_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Range::merge(ranges))
|
Ok(Self::merge(ranges))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge any overlapping ranges
|
/// Merge any overlapping ranges
|
||||||
///
|
///
|
||||||
/// Is guaranteed to return only disjoint ranges in a sorted order.
|
/// Is guaranteed to return only disjoint ranges in a sorted order.
|
||||||
fn merge(mut ranges: Vec<Self>) -> Vec<Self> {
|
fn merge(mut ranges: Vec<Self>) -> Vec<Self> {
|
||||||
ranges.sort();
|
ranges.sort();
|
||||||
|
@ -107,36 +107,24 @@ impl Range {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn complement(ranges: &[Range]) -> Vec<Range> {
|
pub fn complement(ranges: &[Range]) -> Vec<Range> {
|
||||||
|
let mut prev_high = 0;
|
||||||
let mut complements = Vec::with_capacity(ranges.len() + 1);
|
let mut complements = Vec::with_capacity(ranges.len() + 1);
|
||||||
|
|
||||||
if !ranges.is_empty() && ranges[0].low > 1 {
|
for range in ranges {
|
||||||
complements.push(Range {
|
if range.low > prev_high + 1 {
|
||||||
low: 1,
|
complements.push(Range {
|
||||||
high: ranges[0].low - 1,
|
low: prev_high + 1,
|
||||||
});
|
high: range.low - 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
prev_high = range.high;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ranges_iter = ranges.iter().peekable();
|
if prev_high < usize::MAX - 1 {
|
||||||
loop {
|
complements.push(Range {
|
||||||
match (ranges_iter.next(), ranges_iter.peek()) {
|
low: prev_high + 1,
|
||||||
(Some(left), Some(right)) => {
|
high: usize::MAX - 1,
|
||||||
if left.high + 1 != right.low {
|
});
|
||||||
complements.push(Range {
|
|
||||||
low: left.high + 1,
|
|
||||||
high: right.low - 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(Some(last), None) => {
|
|
||||||
if last.high < usize::MAX - 1 {
|
|
||||||
complements.push(Range {
|
|
||||||
low: last.high + 1,
|
|
||||||
high: usize::MAX - 1,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
complements
|
complements
|
||||||
|
@ -172,7 +160,7 @@ pub fn contain(ranges: &[Range], n: usize) -> bool {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::Range;
|
use super::{complement, Range};
|
||||||
|
|
||||||
fn m(a: Vec<Range>, b: Vec<Range>) {
|
fn m(a: Vec<Range>, b: Vec<Range>) {
|
||||||
assert_eq!(Range::merge(a), b);
|
assert_eq!(Range::merge(a), b);
|
||||||
|
@ -181,7 +169,7 @@ mod test {
|
||||||
fn r(low: usize, high: usize) -> Range {
|
fn r(low: usize, high: usize) -> Range {
|
||||||
Range { low, high }
|
Range { low, high }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn merging() {
|
fn merging() {
|
||||||
// Single element
|
// Single element
|
||||||
|
@ -212,26 +200,35 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Last one joins the previous two
|
// Last one joins the previous two
|
||||||
m(
|
m(vec![r(10, 20), r(30, 40), r(20, 30)], vec![r(10, 40)]);
|
||||||
vec![
|
|
||||||
r(10,20),
|
|
||||||
r(30,40),
|
|
||||||
r(20,30),
|
|
||||||
],
|
|
||||||
vec![r(10,40)]
|
|
||||||
);
|
|
||||||
|
|
||||||
m(
|
m(
|
||||||
vec![
|
vec![r(10, 20), r(30, 40), r(50, 60), r(20, 30)],
|
||||||
r(10,20),
|
vec![r(10, 40), r(50, 60)],
|
||||||
r(30,40),
|
|
||||||
r(50,60),
|
|
||||||
r(20,30),
|
|
||||||
],
|
|
||||||
vec![r(10,40), r(50,60)]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Merge adjacent ranges
|
// Merge adjacent ranges
|
||||||
m(vec![r(1, 3), r(4, 6)], vec![r(1, 6)])
|
m(vec![r(1, 3), r(4, 6)], vec![r(1, 6)])
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#[test]
|
||||||
|
fn complementing() {
|
||||||
|
// Simple
|
||||||
|
assert_eq!(complement(&[r(3, 4)]), vec![r(1, 2), r(5, usize::MAX - 1)]);
|
||||||
|
|
||||||
|
// With start
|
||||||
|
assert_eq!(
|
||||||
|
complement(&[r(1, 3), r(6, 10)]),
|
||||||
|
vec![r(4, 5), r(11, usize::MAX - 1)]
|
||||||
|
);
|
||||||
|
|
||||||
|
// With end
|
||||||
|
assert_eq!(
|
||||||
|
complement(&[r(2, 4), r(6, usize::MAX - 1)]),
|
||||||
|
vec![r(1, 1), r(5, 5)]
|
||||||
|
);
|
||||||
|
|
||||||
|
// With start and end
|
||||||
|
assert_eq!(complement(&[r(1, 4), r(6, usize::MAX - 1)]), vec![r(5, 5)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue