Более быстрый способ узнать количество цифр в числе и распечатать его?

У меня есть вопрос, заданный моим учителем информатики, чтобы узнать количество двухзначного числа и трехзначного числа и завершить программу (когда пользователь вводит 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);
    }
}

Я хотел знать, есть ли более короткий способ выполнить ту же задачу? Например, используя arrays , string или Bitswise operator и т. д. Также я бы предпочел, чтобы вы рассказали, как это сделать, а не просто программу, поскольку я учусь и хочу решить это самостоятельно.

Редактировать: извините, потому что я забыл назвать одну вещь - под словом быстрее я на самом деле имел в виду скорость (и более или менее размер программы тоже)


person frunkad    schedule 11.07.2014    source источник
comment
Вы можете вести обратный отсчет от более высоких цифр вместо проверки обоих концов каждого диапазона.   -  person chrylis -cautiouslyoptimistic-    schedule 11.07.2014
comment
Быстрее в чем? По скорости это должно быть довольно быстро.   -  person Dave Newton    schedule 11.07.2014
comment
Однако это не связано, но прекратите использовать DataInputStream.readLine(), этот метод давно устарел, я думаю, с JDK 1.1, вместо этого используйте либо BufferedReader.readLine(), либо используйте DataInputStream.readUTF()   -  person nIcE cOw    schedule 11.07.2014
comment
Нет, нет (заметно) более быстрого способа. Асимптотически говоря, вы не можете быть лучше, чем линейное, и ~ 6 сравнений намного быстрее, чем так называемое optimalizations с использованием дорогой функции log10.   -  person kajacx    schedule 11.07.2014


Ответы (3)


Основываясь на идее использования 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));
}

Очевидно, что если пользователь введет число, состоящее из более чем трех цифр, программа рухнет, поэтому, если вы хотите поддержать это, вы можете добавить проверки границ.

Если под «быстрее» вы подразумеваете «проще», то в этом решении определенно меньше строк...

person Boris the Spider    schedule 11.07.2014
comment
Я согласен, что это хорошая программа, но когда я ввожу случайное число 19431, она показывает ошибку. (java.lang.ArrayIndexOutOfBoundsException: 4) - person frunkad; 11.07.2014
comment
@DarshanJain разве это не то, что говорит мой ответ, так что, если вы хотите поддержать это, вы можете добавить проверки границ? Добавьте несколько проверок границ. - person Boris the Spider; 11.07.2014
comment
да, я только что изменил digits[(int) Math.floor(Math.log10(n))]++; на int x = (int) Math.floor(Math.log10(n)); digits[(x >= 0 && x <3)?x:0]++;, и теперь все работает отлично. - person frunkad; 11.07.2014
comment
@kajacx прочитал последнюю строку ответа. Кроме того, я совершенно уверен, что ограничивающим фактором здесь является ввод данных пользователем. - person Boris the Spider; 11.07.2014

Простой способ подсчитать количество цифр десятичного числа — использовать логарифмическая база 10. Это даст вам десятичное значение того, до какой степени нужно возвести 10, чтобы получить входное значение.

Например, log10(10) даст 1, log10(100) даст 2, а значения между ними дадут значение от 1 до 2. Вы можете взять floor этого результата и добавить 1, чтобы получить количество цифр в заданном числе.

person tredontho    schedule 11.07.2014
comment
Тем не менее, вычисление логарифма числа будет быстрее, чем проверка менее 100? иначе меньше 10? Вы использовали этот подход в коде OP? - person Joshua Taylor; 11.07.2014
comment
Я не думаю, что вопрос ОП на самом деле сосредоточен на скорости здесь. Код, который он запускает, и расчет журнала не будут сильно отличаться. - person noMAD; 11.07.2014
comment
Хм, на самом деле, мы все равно говорим о довольно маленьких значениях, поэтому я не уверен, какое преимущество будет иметь тот или иной метод по сравнению с другими... Вам, вероятно, придется попробовать, чтобы сделать медленный метод. Но да, я думаю, что просто выполнять проверки if(...), вероятно, быстрее, но если ОП когда-либо захочет масштабироваться, чтобы сказать, 3,4,..., n цифр, я думаю, что это было бы неплохо путь :) - person tredontho; 11.07.2014
comment
Возможно, не хватает только Integer.signum проверки, чтобы убедиться, что отрицательные значения учтены должным образом; и, конечно же, обработка случая 0. - person user268396; 11.07.2014
comment
@user268396 user268396 OP запросил метод для полной программы, я уверен, что они могли бы заполнить пробелы :) - person tredontho; 11.07.2014
comment
Немного смущен. не могли бы вы привести пример кода? Это похоже на то, что дал Паук Борис? - person frunkad; 11.07.2014

Поскольку вы читаете строки из входных данных, было бы проще просто проверить, что строка содержит только цифры, а затем взять длину строки как количество цифр.

Не требуется синтаксический анализ введенного числа.

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;
}
person Durandal    schedule 11.07.2014
comment
lineString.length() вернет неправильное значение для отрицательных чисел. - person Pr0gr4mm3r; 11.07.2014
comment
Это абсолютно ничего не меняет в принципе. Образец просто не учитывал это. - person Durandal; 11.07.2014