Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 两个迭代器之间的差异<;范围<;使用>&燃气轮机';s_Algorithm_Rust_Range - Fatal编程技术网

Algorithm 两个迭代器之间的差异<;范围<;使用>&燃气轮机';s

Algorithm 两个迭代器之间的差异<;范围<;使用>&燃气轮机';s,algorithm,rust,range,Algorithm,Rust,Range,我的程序将集合表示为迭代器,我正在尝试实现集合减法 本质上,我试图创建一个函数set_diff,以便: let a = vec![1..5, 7..10]; let a = a.into_iter(); let b = vec![3..9]; let b = b.into_iter(); let mut c = set_diff(a, b); assert_eq!(c.next(), Some(1..3)); assert_eq!(c.next(), Some(9..10)); assert

我的程序将集合表示为迭代器,我正在尝试实现集合减法

本质上,我试图创建一个函数
set_diff
,以便:

let a = vec![1..5, 7..10];
let a = a.into_iter();

let b = vec![3..9];
let b = b.into_iter();

let mut c = set_diff(a, b);
assert_eq!(c.next(), Some(1..3));
assert_eq!(c.next(), Some(9..10));
assert_eq!(c.next(), None);
由于此代码应与
#[no_std]
一起运行,这一点变得复杂。如果有帮助的话,真正的迭代器
a
b
可以被克隆

我已经为两个范围的差异制作了一个可能有效的迭代器,如下所示。我所想到的唯一可能的解决方案是,对B中的每一个元素,在A的每一个元素上进行平面映射,但这确实是低效的

use std::cmp::{max, min};
use std::ops::Range;

/// An extension for Ranges allowing subtraction.
pub trait RangeExt<T: Ord> {
    fn difference(self, other: Self) -> DiffIter<T>;
}

impl RangeExt<usize> for Range<usize> {
    fn difference(self, other: Range<usize>) -> DiffIter<usize> {
        DiffIter {
            state: Some(match (self.start < other.start, self.end < other.end) {
                (false, false) => DiffIterState::One(Range {
                    start: max(other.end, self.start),
                    end: self.end,
                }),
                (false, true) => DiffIterState::None,
                (true, false) => DiffIterState::Two(Range {
                    start: self.start,
                    end: other.start,
                }, Range {
                    start: other.end,
                    end: self.end,
                }),
                (true, true) => DiffIterState::One(Range {
                    start: self.start,
                    end: if other.start == self.end {
                        self.end
                    } else {
                        min(other.start - 1, self.end)
                    }
                }),
            })
        }
    }
}

/// A iterator for the difference of two ranges.
pub struct DiffIter<T> {
    state: Option<DiffIterState<T>>,
}

impl<T> Iterator for DiffIter<T> {
    type Item = Range<T>;
    fn next(&mut self) -> Option<Range<T>> {
        let (out, next) = match self.state.take().unwrap() {
            DiffIterState::None => {
                (None, DiffIterState::None)
            },
            DiffIterState::One(r) => {
                (Some(r), DiffIterState::None)
            },
            DiffIterState::Two(l, r) => {
                (Some(l), DiffIterState::One(r))
            },
        };
        self.state = Some(next);
        out
    }
}

enum DiffIterState<T> {
    None,
    One(Range<T>),
    Two(Range<T>, Range<T>),
}
使用std::cmp::{max,min};
使用std::ops::Range;
///允许减法的范围的扩展。
酒吧特征范围{
fn差异(自我,其他:自我)->困难者;
}
范围的impl RangeExt{
fn差异(自身、其他:范围)->DiffIter{
困难者{
状态:部分(匹配(self.startDiffIterState::一(范围{
开始:最大值(另一端,自启动),
结束:self.end,
}),
(false,true)=>DiffIterState::None,
(真、假)=>DiffIterState::2(范围{
开始:self.start,
结束:其他。开始,
},范围{
开始:另一个,
结束:self.end,
}),
(真,真)=>DiffIterState::一(范围{
开始:self.start,
结束:如果other.start==self.end{
自我终结
}否则{
最小值(其他开始-1,自身结束)
}
}),
})
}
}
}
///两个范围之差的迭代器。
pub-struct-DiffIter{
国家:选择权,
}
DiffIter的impl迭代器{
类型项目=范围;
fn下一步(&mut self)->选项{
let(out,next)=匹配self.state.take().unwrap(){
DiffIterState::无=>{
(无,区分状态::无)
},
DiffIterState::一(r)=>{
(部分(r),不同状态::无)
},
二(l,r)=>{
(一些(l),不同的状态::一(r))
},
};
self.state=Some(下一步);
出来
}
}
不同状态枚举{
没有一个
一个(范围),
二(范围,范围),,
}

几个问题:(1)是否保证迭代器的范围不重叠,(2)是否保证它们的范围是有序的,(3)到目前为止您尝试过什么?编辑以显示我在睡觉前尝试过的内容。@MatthieuM(1)是的,(2)我相信A是,B绝对不是,(3)编辑如果B没有排序,您就有麻烦了。我能想到的最简单的解决方案是
收集
将所有范围放入一个
Vec
,对其进行排序,然后对其进行迭代。不幸的是,
Vec
本身无法存储到生成的迭代器中,因此您首先需要创建一个
struct
,然后实现
IntoIterator
,以生成特殊的
迭代器。