fn main() {
show({
let number = b"123456";
for sequence in number.windows(6) {
let product = sequence.iter().fold(1, |a, &b| a * (b as u64));
println!("product of {:?} is {}", sequence, product);
}
});
}
与其输出“49,50,51,52,53,54是15312500000的乘积”,我需要括号中的正常数字和产品的标准化结果。试图用- b'0'
减去48,以得到第5行的正常数字,这是行不通的。
a * ((b as u64) -b'0')
或
(a - b'0') * (b as u64)
似乎我在这里遗漏了一些东西,例如,我不知道折叠()中的'a‘和'b’值到底是什么。有人能启发我吗?)
发布于 2015-02-28 04:32:54
看看fold
,我们可以看到它需要两个参数:
fn fold<B, F>(self, init: B, f: F) -> B
where F: FnMut(B, Self::Item) -> B
init
是一些任意类型的B
,f
是一个从迭代器获取B
值和元素的闭包,以计算一个新的B
值。整个函数返回一个B
。这些类型强烈地暗示了发生了什么:在迭代器的连续元素上反复调用闭包f
,将计算出来的B
值传递给下一个f
调用。检查实施确认了这种怀疑:
let mut accum = init;
for x in self {
accum = f(accum, x);
}
accum
它通过迭代器运行,将累积的状态传递到闭包中,以便计算下一个状态。
首先,让我们将类型放在fold
调用上:
let product = sequence.iter().fold(1, |a: u64, &b: &u8| a * (b as u64));
也就是说,我们想要的B
类型是u64
(这是我们的最终产品),迭代器的项目类型是&u8
,是对一个字节的引用。
现在,我们可以手动地内联fold
的定义来计算product
,以试图澄清所需的行为(我现在忽略了规范化):
let mut accum = 1;
for x in sequence.iter() {
accum = { // the closure
let a: u64 = accum;
let &b: &u8 = x;
a * b as u64
}
}
let product = accum;
简化:
let mut product = 1;
for &b in sequence.iter() {
product = product * (b as u64)
}
希望这能让我们更清楚地知道需要发生什么:b
跨每个字节运行,因此需要调整的值将ASCII编码的值降到预期的0..10范围。
所以,你是对的:
a * ((b as u64) -b'0')
但是,细节意味着编译失败,但类型错误:b'0'
有u8
类型,而b as u64
类型为u64
,在u64
和u8
中使用-
是不合法的。移动在u64
转换之前进行的正常化将确保此操作正常,因为那时您正在减去b
(即u8
)和u8
product * (b - b'0') as u64
总之,fold
看上去可能更清晰(而且实际工作)如下:
let product = sequence.iter()
.fold(1, |prod, &byte| prod * (byte - b'0') as u64);
(我为在IRC上给你这么混乱的代码而道歉。)
发布于 2015-02-28 14:41:14
作为fold
的替代方案,您可以使用map
和MultiplicativeIterator::product
。我发现这两个步骤有助于更清楚地了解正在发生的事情。
#![feature(core)]
use std::iter::MultiplicativeIterator;
fn main() {
let number = b"123456";
for sequence in number.windows(6) {
let product = sequence.iter().map(|v| (v - b'0') as u64).product();
println!("product of {:?} is {}", sequence, product);
}
}
您甚至可以选择将大小从u8
拆分到u64
。
sequence.iter().map(|v| v - b'0').map(|v| v as u64).product();
发布于 2020-12-24 11:13:43
现在,另一种选择是product
+ to_digit
:(itertools
用于打印迭代器的内容)
use {itertools::Itertools, std::char};
fn main() {
let number = b"123456";
let sequence = number
.iter()
.map(|&c| u64::from(char::from(c).to_digit(10).expect("not a digit")));
let product: u64 = sequence.clone().product();
println!("product of {:?} is {}", sequence.format(", "), product);
}
(游乐场)
https://stackoverflow.com/questions/28777933
复制相似问题