2

I have a question given by my computer teacher to find out the number of two digit number and three digit number and terminate the program (when user enter 0 )and print the total two digit ,three digit numbers and other digit number.

This is an example output in terminal window:

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

This is my program :

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);
    }
}

I wished to know if there was any shorter way to do the same task ? Like using arrays , string or Bitswise operator , etc. Also I would rather like if you would tell the method of how to do it instead of simply the program as I am a learning student and wish to solve it out myself.

Edit: Sorry because i forgot to term one thing - by the word quicker i actually meant for speed (and more or less , size of program too)

frunkad
  • 2,433
  • 1
  • 23
  • 35
  • You could count down from higher digits instead of checking both ends of each range. – chrylis -cautiouslyoptimistic- Jul 11 '14 at 16:05
  • 2
    Quicker in what way? Speed-wise that should be pretty quick. – Dave Newton Jul 11 '14 at 16:06
  • Not related though, but stop using `DataInputStream.readLine()`, this method has been deprecated since long, I guess since `JDK 1.1`, instead use either `BufferedReader.readLine()` or else use `DataInputStream.readUTF()` – nIcE cOw Jul 11 '14 at 16:23
  • No, there is no (noticably) faster way. Asymptotically skpeaking, you cannot be better than linear and ~6 comparations are way faster then so-called `optimalizations` using expensive `log10` function. – kajacx Jul 11 '14 at 16:49

3 Answers3

1

An easy way to calculate the number of digits of a decimal number is to use the log base 10. This will give you a decimal value of what power to raise 10 to in order to get the input value.

For example, log10(10) would give 1, log10(100) would give 2, and values in between would give a value between 1 and 2. You could take the floor of this result, and add 1 to get the number of digits in the given number.

tredontho
  • 1,273
  • 10
  • 14
  • 1
    Still, is computing the logarithm of the number going be to faster than checking "less than 100? else less than 10?" Did you time this approach in OP's code? – Joshua Taylor Jul 11 '14 at 16:08
  • I don't think the OP's question is actually focusing on the speed here. The code he is running, and the calculation of a log is not going to be immensely different. – noMAD Jul 11 '14 at 16:10
  • Hmm, realistically, we're talking about pretty small values anyway, so I'm not sure how much of an edge any given method will have over others... You'd probably have to try in order to make a slow method. But yes, I think that just doing the if(...) checks is probably faster, but if the OP ever wanted to scale up to say, 3,4,...,n digits, I think this would be a nice way to go :) – tredontho Jul 11 '14 at 16:11
  • Perhaps the only thing missing is `Integer.signum` checking, to make sure negative values are properly accounted for; and of course handling the case of 0. – user268396 Jul 11 '14 at 16:14
  • @user268396 OP did ask for method over a full program, I'm sure they could fill in the blanks :) – tredontho Jul 11 '14 at 16:17
  • A bit confused . can you please give a code example ? Is it like the one given by Boris the Spider ? – frunkad Jul 11 '14 at 16:31
0

Since you're reading strings from the input, it would be less processing complex to just check that the string contains only digits and then take the string length as number of digits.

No parsing of the number actually entered needed.

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;
}
Durandal
  • 19,919
  • 4
  • 36
  • 70
0

Building on the idea of using log10 to determine the number of digits, use an array to store the number of numbers with a certain number of digits.

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));
}

Obviously if the user enters a number with more than three digits, the program will crash - so if you want to support that you could add bounds checks.

If by "quicker" you means "easier" then this solution certainly has fewer lines...

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
  • i agree it is good program but when i enter a random number 19431, it showed an error. (java.lang.ArrayIndexOutOfBoundsException: 4 ) – frunkad Jul 11 '14 at 16:27
  • @DarshanJain isn't that what my answer says _so if you want to support that you could add bounds checks_? Add some bounds checks. – Boris the Spider Jul 11 '14 at 16:34
  • ya i just changed the `digits[(int) Math.floor(Math.log10(n))]++;` to `int x = (int) Math.floor(Math.log10(n)); digits[(x >= 0 && x <3)?x:0]++;` and now it works very fine. – frunkad Jul 11 '14 at 16:45
  • @kajacx read the last line of the answer. Also, I'm fairly sure user input is the limiting factor here. – Boris the Spider Jul 11 '14 at 18:13