首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Collatz序列

Collatz序列
EN

Code Review用户
提问于 2014-04-02 11:38:13
回答 5查看 11.2K关注 0票数 17

我是一个初学者,我只知道有限的数量,如ifwhiledo while。因此,我来这里是为了检查我是否在用最好的实践和最有效的方法来编写我目前所知的代码。

代码语言:javascript
复制
import java.util.Scanner;


public class SixtyTwo {

    public static void main(String[] args) {

            Scanner keyboard = new Scanner(System.in);

            System.out.print("Starting Number: ");
            int n = keyboard.nextInt();
            int counter = 0;
            int stepsTaken = 0;
            int largestNumber = 0;
            System.out.println();

            while ( n != 1 ){
                    if ( ( n & 1 ) == 0 ) {
                            System.out.print( (n = ( n / 2 )) + " " );
                            stepsTaken++;
                            counter++;
                    }       else {
                            System.out.print( (n = ( n * 3 ) + 1) + " " );
                            stepsTaken++;
                            counter++;
                    }

                    if ( n > largestNumber ){
                            largestNumber = n;
                    }

                    if (counter == 9){
                            counter = 0;
                            System.out.print("\n");
                    }
            }

            System.out.println();
            System.out.println("\nTerminated after " + stepsTaken + " steps.");
            System.out.println("The largest value was " + largestNumber + ".");
    }
}
EN

回答 5

Code Review用户

回答已采纳

发布于 2014-04-02 11:57:02

这是一些总体上相当不错的代码,但是我有一些评论。

  • 当您完成输入时,应该关闭Scanner。只需在获得所需的输入时调用keyboard.close();即可。
  • 您的类名为SixtyTwo,但我不知道这与任何事情有什么关系。更好的名字是Collatz
  • if ( ( n & 1 ) == 0 )虽然是一种很好的检查数字是否为偶数的方法,但对于% (模块化)操作符来说,它更容易读懂。我会用if (n % 2 == 0)
  • System.out.print( (n = ( n / 2 )) + " " );,...now,我不太喜欢这个。当然,它可以修改一个值并将其输出到同一行,但是我会将赋值分离到它自己的行中。在一行上分配,在另一行上输出,使事情变得更加清晰。
  • stepsTaken++;counter++;不需要在if - matter块中,将它们放在它们之外,因为不管您的条件是真是假,它们总是会被执行。
  • if (counter == 9)可以改为if (stepsTaken % 9 == 0),这将完全消除对counter变量的需求。
票数 11
EN

Code Review用户

发布于 2014-04-02 12:22:05

通过使用三元操作符,可以大大降低代码的复杂性:

代码语言:javascript
复制
while (n != 1){
   stepsTaken++;
   n = (n % 2 == 0) ? n / 2 : n * 3 + 1;
   System.out.print(n);

   //Your largest number and the linebreaks go here;
}

正如您正确地提到的,我删除了counter++,您可以代替counter == 9使用stepsTaken % 9 == 0

小解释:

这是:

代码语言:javascript
复制
int i = {some value};
if(i % 2 == 0){
   i = i / 2;
}
else {
   i = i * 3 + 1;
}

可以缩短为三层操作符。它有以下语法:

代码语言:javascript
复制
i = (condition) ? if-branch : else-branch;

这就是缩短代码背后的全部魔力。

票数 8
EN

Code Review用户

发布于 2014-04-02 16:31:03

既然这段代码的全部目的是检查Collatz猜想(它说,不管你从哪一个整数开始,你最终将在1结束,你不会得到一个重复的循环或数字增长越来越多),我是否可以建议你添加一个检查,这个数字不会变得太大。因为如果有一个序列增长和增长的数字,那么你就会得到一个溢出,然后从那时起得到序列中的错误结果。

通常,如果n是奇数且3n +1> 2^31 - 1,或者n> 715,827,882,则会得到错误的结果。我敢打赌,你不需要搜索很远,以找到一个数字,在这个限制被超越。如果没有这样的检查,整个代码就毫无意义。

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

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

复制
相关文章

相似问题

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