首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将ASCII数字规范化为数字数字

将ASCII数字规范化为数字数字
EN

Stack Overflow用户
提问于 2015-02-28 03:56:52
回答 3查看 625关注 0票数 2

(e: T) { println!("{:?}", e) } fn main() { show({ let number = b"122222"; for sequence in number.windows(6) { let product = sequence.iter().fold(1, |a, &b| a * (b as u64)); println!("product of {:?} is {}", sequence, product); } }); }">在play.锈病-lang.org上运行示例

代码语言:javascript
运行
复制
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行的正常数字,这是行不通的。

代码语言:javascript
运行
复制
a * ((b as u64) -b'0')

代码语言:javascript
运行
复制
(a - b'0') * (b as u64)

似乎我在这里遗漏了一些东西,例如,我不知道折叠()中的'a‘和'b’值到底是什么。有人能启发我吗?)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-28 04:32:54

看看fold,我们可以看到它需要两个参数:

代码语言:javascript
运行
复制
fn fold<B, F>(self, init: B, f: F) -> B
   where F: FnMut(B, Self::Item) -> B

init是一些任意类型的Bf是一个从迭代器获取B值和元素的闭包,以计算一个新的B值。整个函数返回一个B。这些类型强烈地暗示了发生了什么:在迭代器的连续元素上反复调用闭包f,将计算出来的B值传递给下一个f调用。检查实施确认了这种怀疑:

代码语言:javascript
运行
复制
let mut accum = init;
for x in self {
    accum = f(accum, x);
}
accum

它通过迭代器运行,将累积的状态传递到闭包中,以便计算下一个状态。

首先,让我们将类型放在fold调用上:

代码语言:javascript
运行
复制
let product = sequence.iter().fold(1, |a: u64, &b: &u8| a * (b as u64));

也就是说,我们想要的B类型是u64 (这是我们的最终产品),迭代器的项目类型是&u8,是对一个字节的引用。

现在,我们可以手动地内联fold的定义来计算product,以试图澄清所需的行为(我现在忽略了规范化):

代码语言:javascript
运行
复制
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;

简化:

代码语言:javascript
运行
复制
let mut product = 1;
for &b in sequence.iter() {
    product = product * (b as u64)
}

希望这能让我们更清楚地知道需要发生什么:b跨每个字节运行,因此需要调整的值将ASCII编码的值降到预期的0..10范围。

所以,你是对的:

代码语言:javascript
运行
复制
a * ((b as u64) -b'0')

但是,细节意味着编译失败,但类型错误:b'0'u8类型,而b as u64类型为u64,在u64u8中使用-是不合法的。移动在u64转换之前进行的正常化将确保此操作正常,因为那时您正在减去b (即u8)和u8

代码语言:javascript
运行
复制
product * (b - b'0') as u64

总之,fold看上去可能更清晰(而且实际工作)如下:

代码语言:javascript
运行
复制
let product = sequence.iter()
    .fold(1, |prod, &byte| prod * (byte - b'0') as u64);

(我为在IRC上给你这么混乱的代码而道歉。)

票数 3
EN

Stack Overflow用户

发布于 2015-02-28 14:41:14

作为fold的替代方案,您可以使用mapMultiplicativeIterator::product。我发现这两个步骤有助于更清楚地了解正在发生的事情。

代码语言:javascript
运行
复制
#![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

代码语言:javascript
运行
复制
sequence.iter().map(|v| v - b'0').map(|v| v as u64).product();
票数 0
EN

Stack Overflow用户

发布于 2020-12-24 11:13:43

现在,另一种选择是product + to_digit:(itertools用于打印迭代器的内容)

代码语言:javascript
运行
复制
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);
}

(游乐场)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28777933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档