【问题标题】:A quicker method for finding out the number of digits in a number and print it?找出数字中位数并打印出来的更快方法?
【发布时间】:2014-07-11 15:59:44
【问题描述】:

我的计算机老师提出了一个问题,要找出两位数和三位数的个数并终止程序(当用户输入 0 时)并打印总的两位数,三位数和其他位数。

这是终端窗口中的示例输出:

Enter your number: 23
Enter your number: 1
Enter your number: 412
Enter your number: -123
Enter your number: 32332
Enter your number: 12
Enter your number: -1
Enter your number: 0
Two digit numbers : 2
Three digit numbers : 2
Other digit numbers : 3

这是我的程序:

import java.io.*;
public class two_three_digits
{
    static DataInputStream dis = new DataInputStream(System.in);
    static void main()throws IOException
    {
        int two = 0 , three = 0 , oth = 0;
        while(true)
        {
            System.out.print("Enter your number: ");
            int n = Integer.parseInt(dis.readLine());
            n = (int)Math.abs(n);
            int d = 0,cn = n;
            if(n == 0)break;
            else if(n > 9 && n < 100)two++;
            else if(n > 99 && n <1000)three++;
            else oth++;
        }
        System.out.println("Two digit numbers : "+two);
        System.out.println("Three digit numbers : "+three);
        System.out.println("Other digit numbers : "+oth);
    }
}

我想知道是否有更短的方法来完成相同的任务?比如使用 arraysstringBitswise operator 等。 另外我希望你能告诉我如何做的方法而不是简单的程序,因为我是一个学习的学生,希望自己解决它。

编辑:抱歉,因为我忘了用“更快”这个词来形容一件事——我实际上是指速度(或多或少,程序的大小)

【问题讨论】:

  • 你可以从高位倒数,而不是检查每个范围的两端。
  • 以什么方式更快?速度方面应该很快。
  • 虽然不相关,但停止使用DataInputStream.readLine(),这个方法已经被弃用很久了,我猜从JDK 1.1开始,改用BufferedReader.readLine()或者使用DataInputStream.readUTF()
  • 不,没有(明显)更快的方法。渐近地说,你不能比线性更好,而且〜6个比较比使用昂贵的log10函数的所谓optimalizations快得多。

标签: java digits


【解决方案1】:

计算十进制数位数的一种简单方法是使用log base 10。这将为您提供将 10 提高到的十进制值以获得输入值。

例如,log10(10) 会给出 1,log10(100) 会给出 2,而介于两者之间的值会给出介于 1 和 2 之间的值。您可以取此结果的 floor,然后加 1 得到给定数字的位数。

【讨论】:

  • 仍然,计算数字的对数是否比检查“小于 100?否则小于 10?”更快?您是否在 OP 的代码中为这种方法计时?
  • 我不认为 OP 的问题实际上是关注这里的速度。他正在运行的代码和日志的计算不会有太大的不同。
  • 嗯,实际上,无论如何我们都在谈论非常小的值,所以我不确定任何给定方法比其他方法有多少优势......你可能不得不尝试为了制作一个缓慢的方法。但是,是的,我认为仅执行 if(...) 检查可能会更快,但是如果 OP 想要扩大到 3,4,...,n 位,我认为这将是一个不错的选择要走的路:)
  • 也许唯一缺少的是Integer.signum 检查,以确保正确考虑负值;当然还要处理 0 的情况。
  • @user268396 OP 确实要求提供完整程序的方法,我相信他们可以填补空白 :)
【解决方案2】:

基于使用log10确定位数的思想,使用数组来存储一定位数的数字的个数。

public static void main(final String[] args) throws InterruptedException {
    int[] digits = new int[3];
    final Console c = System.console();
    while (true) {
        final int n = Math.abs(Integer.parseInt(c.readLine("Enter your number: ")));
        if (n == 0) {
            break;
        }
        digits[(int) Math.floor(Math.log10(n))]++;
    }
    System.out.println(Arrays.toString(digits));
}

很明显,如果用户输入的数字超过三位数,程序就会崩溃——所以如果你想支持,你可以添加边界检查。

如果“更快”是指“更容易”,那么这个解决方案的行数肯定会更少......

【讨论】:

  • 我同意这是一个很好的程序,但是当我输入一个随机数 19431 时,它显示了一个错误。 (java.lang.ArrayIndexOutOfBoundsException: 4)
  • @DarshanJain 不是我的回答所说的所以如果你想支持你可以添加边界检查?添加一些边界检查。
  • 是的,我刚刚将digits[(int) Math.floor(Math.log10(n))]++; 更改为int x = (int) Math.floor(Math.log10(n)); digits[(x &gt;= 0 &amp;&amp; x &lt;3)?x:0]++;,现在它工作得很好。
  • @kajacx 阅读了答案的最后一行。另外,我很确定用户输入是这里的限制因素。
【解决方案3】:

由于您正在从输入中读取字符串,因此只需检查字符串是否仅包含数字,然后将字符串长度作为数字的数量,处理起来会不太复杂。

不需要解析实际输入的数字。

String lineString = dis.readLine()
// check for valid input here (if needed)
int l = lineString.length();
if (lineString.charAt(0) == '-') // for negative numbers
    --l;
switch (l) {
    default:
        oth++;
        break;
    case 2:
        two++;
        break;
    case 3:
        three++;
        break;
}

【讨论】:

  • lineString.length() 将返回负数的错误值。
  • 这在原则上完全没有改变。示例只是没有说明这一点。
猜你喜欢
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2011-01-03
相关资源
最近更新 更多