Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.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
Rust 如何重用拆分空白迭代器?_Rust - Fatal编程技术网

Rust 如何重用拆分空白迭代器?

Rust 如何重用拆分空白迭代器?,rust,Rust,我有一段代码,它应该检查两个句子是否“太相似”,这是由一个启发式代码定义的,这个启发式代码最清晰 fn too_similar(thing1: &String, thing2: &String) -> bool { let split1 = thing1.split_whitespace(); let split2 = thing2.split_whitespace(); let mut matches = 0; for s1 in spl

我有一段代码,它应该检查两个句子是否“太相似”,这是由一个启发式代码定义的,这个启发式代码最清晰

fn too_similar(thing1: &String, thing2: &String) -> bool {
    let split1 = thing1.split_whitespace();
    let split2 = thing2.split_whitespace();

    let mut matches = 0;
    for s1 in split1 {
        for s2 in split2 {
            if s1.eq(s2) {
                matches = matches + 1;
                break;
            }
        }
    }

    let longer_length =
        if thing1.len() > thing2.len() {
            thing1.len()
        } else {
            thing2.len()
        };

    matches > longer_length / 2
}
但是,我得到了以下编译错误:

错误[E0382]:使用移动值:`split2`
-->src/main.rs:7:19
|
7 |用于拆分2中的s2{
|^^^^^值在循环的上一次迭代中移动到此处
|

=注意:发生移动是因为'split2'具有类型'std::str::SplitWhitespace
split2
正在移动,因为使用
for
进行迭代会消耗迭代器,并且由于该类型未实现
复制
,Rust不会隐式复制它

您可以通过在
的第一个
中创建新的迭代器来解决此问题:

let split1 = thing1.split_whitespace();

let mut matches = 0;
for s1 in split1 {
    for s2 in thing2.split_whitespace() {
        if s1.eq(s2) {
            matches = matches + 1;
            break;
        }
    }
}
...
您还可以使用
迭代器
特性中的一些高阶函数重写
匹配
计数循环:

let matches = thing1.split_whitespace()
    .flat_map(|c1| thing2.split_whitespace().filter(move |&c2| c1 == c2))
    .count();
longer_length
也可以写成:

let longer_length = std::cmp::max(thing1.len(), thing2.len());

可能有更好的方法来比较这个词

如果短语很长,那么对
thing1
中的每个单词迭代
thing2
的单词不是很有效。如果您不必担心出现多次的单词,那么
HashSet
可能会有所帮助,并将迭代归结为如下内容:

let words1: HashSet<&str> = thing1.split_whitespace().collect();
let words2: HashSet<&str> = thing2.split_whitespace().collect();
let matches = words1.intersection(&words2).count();
let mut words_hash1: HashMap<&str, usize> = HashMap::new();
for word in thing1.split_whitespace() {
    *words_hash1.entry(word).or_insert(0) += 1;
}
let matches2: usize = thing2.split_whitespace()
                     .map(|s| words_hash1.get(s).cloned().unwrap_or(0))
                     .sum();

感谢您的回复和解决方法。那么,
SplitWhitespace
不应该是可复制的吗?在每个单词上进行拆分似乎效率低下。解释了为什么
SplitWhitespace
不实现
Copy
。此外,这不会比
SplitWhitespace
实现
Copy
慢,因为ERATOR是惰性的,创建
SplitWhitespace
结构的开销与迭代拆分所花费的时间相比可以忽略不计。但令人惊讶的是,它没有实现
Clone