首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >欧拉问题5

欧拉问题5
EN

Code Review用户
提问于 2015-09-28 14:47:04
回答 2查看 153关注 0票数 1

我开始学习Rust,它看起来很棒,但它与任何基于C的语言都不一样。我想知道如何使这段代码更加实用,以及如何改进我的解决方案本身。

欧拉问题5

2520是最小的数,可以除以从1到10的每一个数,没有任何余数。什么是最小的正数,可以被从1到20的所有数字整除?

代码语言:javascript
复制
fn near_pow(number:f64, exponent:f64)-> f64
{
    exponent.powf(number.log(exponent).floor())
}

fn is_prime(number:i32) -> bool
{
    use std::ops::Rem;
    
    if number == 2 { return true; }
    if number.rem(2)== 0 { return false; }
    
    let mut i = 3;
    while (i*i) <= number
    {
        if number.rem(i) == 0 {return false;}
        i+= 2;
    }
    true
}

fn euler_problem5(to:i32) -> f64
{
    (1..to+1).filter(|&x| is_prime(x))
    .fold(1f64, |p , x|p * near_pow(to as f64, x as f64))   
}
fn main() {
    
    let x = euler_problem5(20);
    println!("{}",x);
    
}

链接到操场

EN

回答 2

Code Review用户

回答已采纳

发布于 2015-09-28 15:24:56

  1. 在大多数情况下,铁锈使用“埃及支架”。如果条件{ //块} else { //另一个块}
  2. 在类型中使用:后的空格。fn foo(值:类型)
  3. 在运算符(如==+* )以及符号(如-> )周围使用空格。I += 2;
  4. ,之后使用空格。(“{}”,x);
  5. 没有必要在一行早期返回语句( ;子句)中使用。如果编号== 2{返回true }
  6. 使用%操作符而不是调用rem方法:如果编号%2 == 0{返回false }
  7. 将闭包写到fold内嵌,特别是因为您无法给它命名比fold_op更好的名称(OP更改了我所指的代码;查看修订历史以了解我在说什么)。(1..to + 1).fold(1f64,区p,x区{ // .fold })
  8. 只要有可能,就试着赶走易变性。我也不喜欢循环体内部的return语句(或者在任何地方都不是卫士子句)。尝试使用迭代器代替。

合在一起:

代码语言:javascript
复制
fn near_pow(number: f64, exponent: f64) -> f64 {
    exponent.powf(number.log(exponent).floor())
}

fn is_prime(number: i32) -> bool {
    if number == 2 { return true }
    if number % 2 == 0 { return false }

    (0..)
        .map(|v| 3 + 2 * v) // Can use `Range::step_by` when stable
        .take_while(|i| i * i <= number)
        .all(|i| number % i != 0)
}

fn euler_problem5(to: i32) -> f64 {
    (1..to + 1).fold(1f64, |p, x| {
        if is_prime(x) {
            p * near_pow(to as f64, x as f64)
        } else {
            p
        }
    })
}

fn main() {
    println!("{}", euler_problem5(20));
}

我不太熟悉如何有效地解决欧拉问题,所以希望其他人也能加入进来。

原始代码更改

后的

更新

代码语言:javascript
复制
fn euler_problem5(to: i32) -> f64 {
    (1..to + 1)
        .filter(|&v| is_prime(v))
        .fold(1f64, |p, x| p * near_pow(to as f64, x as f64))
}

基于其他答案的

更新

user5402主张用整数运算代替浮点数,但无论哪种方法,您都应该使用无符号整数,因为不需要支持负数。这也让你对你的价值观有了更多的上限。

票数 1
EN

Code Review用户

发布于 2015-09-28 16:11:08

f64

我最大的批评是,您正在使用浮点算法来解决整数问题。

考虑到舍入错误和不精确答案的可能性,我会选择一个简单的while-循环来计算nearest_pow

(对不起-这是Python,我还不是一个锈蚀程序员)

代码语言:javascript
复制
def nearest_pow(p,n):
  a = 1
  while a*p <= n:
    a = a * p
  return a

铁锈有foldtake_while,所以我相信您可以以一种功能的方式实现这一点。

这是有效的-它只执行日志n迭代-不会遭受任何轮转错误。

此外,它也适用于可能适用于其他数论问题的大整数。

另外,我将以整数的形式返回答案--也许是一个i64

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

https://codereview.stackexchange.com/questions/105930

复制
相关文章

相似问题

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