ChatGPT解决这个技术问题 Extra ChatGPT

How to get the separate digits of an int number?

I have numbers like 1100, 1002, 1022 etc. I would like to have the individual digits, for example for the first number 1100 I want to have 1, 1, 0, 0.

How can I get it in Java?


j
jjnguy

To do this, you will use the % (mod) operator.

int number; // = some int

while (number > 0) {
    print( number % 10);
    number = number / 10;
}

The mod operator will give you the remainder of doing int division on a number.

So,

10012 % 10 = 2

Because:

10012 / 10 = 1001, remainder 2

Note: As Paul noted, this will give you the numbers in reverse order. You will need to push them onto a stack and pop them off in reverse order.

Code to print the numbers in the correct order:

int number; // = and int
LinkedList<Integer> stack = new LinkedList<Integer>();
while (number > 0) {
    stack.push( number % 10 );
    number = number / 10;
}

while (!stack.isEmpty()) {
    print(stack.pop());
}

This will get you the numbers in the wrong order, however, so you'll have to be sure and push them onto a stack or just put them in an array in reverse order.
Note that this gives them right-to-left. (The OP's example shows them left-to-right). Simple enought to handle, but it should be noted.
@Don, in practice, no. I would not favor this. It is way faster than the string based version though. I would look at Marimuthu's answer though for some fast and short code.
Great solution but it looks like it doesn't handle the scenario when the number starts with leading zeros. for example - 001122. If I use above logic - I'll get only 1,1,2,2. The leading 0s are dropped by % and / operations. Please correct me if I am wrong.
what about negative integers here? if I pass -3432, the output will be -2-3-4-3 which is incorrect.
B
BalusC

Convert it to String and use String#toCharArray() or String#split().

String number = String.valueOf(someInt);

char[] digits1 = number.toCharArray();
// or:
String[] digits2 = number.split("(?<=.)");

In case you're already on Java 8 and you happen to want to do some aggregate operations on it afterwards, consider using String#chars() to get an IntStream out of it.

IntStream chars = number.chars();

This is the quick and dirty way.
With split(""), the first item in the array is "". Use other regex, like split("(?<=.)").
toCharArray is MUCH faster than split. I just put both in a loop 1000 times and toCharArray took 20ms and split took 1021ms. I also did it mathematically using divide by ten with mod (%) and it took 50ms doing it that way, so toCharArray appears to be faster than the other two.
Edit: I just did it again, this time with longer loops to be sure (10,000 iterations). toCharArray is about 100 times faster than split, and toCharArray is about 5 times faster than modulus math method.
@BalusC number.chars() will return the result in an Ascii values not a numeric. So that the number "1234" will be splited to "49", "50", "51", "52" instead of "1", "2", "3", "4". To do it right it should look like: IntStream chars = number.chars().map(Character::getNumericValue);
S
Someone Somewhere

How about this?

public static void printDigits(int num) {
    if(num / 10 > 0) {
        printDigits(num / 10);
    }
    System.out.printf("%d ", num % 10);
}

or instead of printing to the console, we can collect it in an array of integers and then print the array:

public static void main(String[] args) {
    Integer[] digits = getDigits(12345);
    System.out.println(Arrays.toString(digits));
}

public static Integer[] getDigits(int num) {
    List<Integer> digits = new ArrayList<Integer>();
    collectDigits(num, digits);
    return digits.toArray(new Integer[]{});
}

private static void collectDigits(int num, List<Integer> digits) {
    if(num / 10 > 0) {
        collectDigits(num / 10, digits);
    }
    digits.add(num % 10);
}

If you would like to maintain the order of the digits from least significant (index[0]) to most significant (index[n]), the following updated getDigits() is what you need:

/**
 * split an integer into its individual digits
 * NOTE: digits order is maintained - i.e. Least significant digit is at index[0]
 * @param num positive integer
 * @return array of digits
 */
public static Integer[] getDigits(int num) {
    if (num < 0) { return new Integer[0]; }
    List<Integer> digits = new ArrayList<Integer>();
    collectDigits(num, digits);
    Collections.reverse(digits);
    return digits.toArray(new Integer[]{});
}

That's a good way to print things in the correct order using mod. +1
This is beautiful. I was thinking: "There has to be a way to reverse the order without using a Collection...." +1
Impeccable. Might want to add following code to getDigits(int num) to make it immune to bad inputs: if (number < 0) { return new Integer[0]; } Tested with following inputs: Integer[] samples = {11111, 123457, 0, -13334, 93846, 87892, 9876543, -1234, 012455};
Z
Zach Langley

I haven't seen anybody use this method, but it worked for me and is short and sweet:

int num = 5542;
String number = String.valueOf(num);
for(int i = 0; i < number.length(); i++) {
    int j = Character.digit(number.charAt(i), 10);
    System.out.println("digit: " + j);
}

This will output:

digit: 5
digit: 5
digit: 4
digit: 2

It is amazing. Thanks
For some reason, this logic gives wrong output for numbers different than 5542. Try for instance: 0142323
@tavalendo 0142323 is an octal constant equal to 50387, due to the leading zero, just like 0x100 is a hexadecimal constant equal to 256, due to the leading 0x, and 0b1011 is a binary constant equal to 11 due to the leading 0b. Be wary of leading 0's on integer constants!
K
Koin Arab

I noticed that there are few example of using Java 8 stream to solve your problem but I think that this is the simplest one:

int[] intTab = String.valueOf(number).chars().map(Character::getNumericValue).toArray();

To be clear: You use String.valueOf(number) to convert int to String, then chars() method to get an IntStream (each char from your string is now an Ascii number), then you need to run map() method to get a numeric values of the Ascii number. At the end you use toArray() method to change your stream into an int[] array.


J
JoakimE

I see all the answer are ugly and not very clean.

I suggest you use a little bit of recursion to solve your problem. This post is very old, but it might be helpful to future coders.

public static void recursion(int number) {
    if(number > 0) {
        recursion(number/10);
        System.out.printf("%d   ", (number%10));
    }
}

Output:

Input: 12345

Output: 1   2   3   4   5 

Damn right you are about answers being ugle. Thanks.
s
slisnychyi

simple solution

public static void main(String[] args) {
    int v = 12345;
    while (v > 0){
        System.out.println(v % 10);
        v /= 10;
    }
}

u
uı6ʎɹnɯ ꞁəıuɐp
// could be any num this is a randomly generated one
int num = (int) (Math.random() * 1000);

// this will return each number to a int variable
int num1 = num % 10;
int num2 = num / 10 % 10;
int num3 = num /100 % 10;

// you could continue this pattern for 4,5,6 digit numbers
// dont need to print you could then use the new int values man other ways
System.out.print(num1);
System.out.print("\n" + num2);
System.out.print("\n" + num3);

Java int type has a minimum value of -2^31 and a maximum value of 2^31-1. How can the above solution work for all +ve values that fit in a int type?
i
ifly6

Since I don't see a method on this question which uses Java 8, I'll throw this in. Assuming that you're starting with a String and want to get a List<Integer>, then you can stream the elements like so.

List<Integer> digits = digitsInString.chars()
        .map(Character::getNumericValue)
        .boxed()
        .collect(Collectors.toList());

This gets the characters in the String as a IntStream, maps those integer representations of characters to a numeric value, boxes them, and then collects them into a list.


Interestingly enough chars() returns an IntStream so if you call boxed() and collect() you can return the List of Integers immediately.
You get ASCII values back. So 1 maps to 49.
Interesting! Didn't know that, ty.
Doesn't compile: Collectors.toList() → "Type mismatch: cannot convert from Collector<Object,capture#3-of ?,List<Object>> to Supplier<R>", collect → "The method collect(Supplier<R>, ObjIntConsumer<R>, BiConsumer<R,R>) in the type IntStream is not applicable for the arguments (Collector<Object,?,List<Object>>)"
Edited. They need to be boxed before collecting. See eg repl.it/@ifly6/HeftyAffectionateHertz#Main.java
S
Simon Forsberg

Java 9 introduced a new Stream.iterate method which can be used to generate a stream and stop at a certain condition. This can be used to get all the digits in the number, using the modulo approach.

int[] a = IntStream.iterate(123400, i -> i > 0, i -> i / 10).map(i -> i % 10).toArray();

Note that this will get the digits in reverse order, but that can be solved either by looping through the array backwards (sadly reversing an array is not that simple), or by creating another stream:

int[] b = IntStream.iterate(a.length - 1, i -> i >= 0, i -> i - 1).map(i -> a[i]).toArray();

or

int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length - i]).toArray();

As an example, this code:

int[] a = IntStream.iterate(123400, i -> i > 0, i -> i / 10).map(i -> i % 10).toArray();
int[] b = IntStream.iterate(a.length - 1, i -> i >= 0, i -> i - 1).map(i -> a[i]).toArray();
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));

Will print:

[0, 0, 4, 3, 2, 1]
[1, 2, 3, 4, 0, 0]

And now a solution without overkill! At least for 000123 and -123 there are funny results :-)
@Kaplan The question is about digits of a number, and "-" is not a digit. Additionally, the number "000123" is the same as just plain "123", unless you claim that it's written in octal or something but in that case it would be a completely different number.
As has been discussed extensively, any solution approach with % has the flaw that leading zeros are omitted (eg. 000123). Only as encore, my solution also works correctly for the signs too. Btw: Your solution gets [8, 3] for 000123.
@Kaplan This question is about getting the separate digits for an int number, not a String number. And naturally 000123 becomes 83 because 123 OCT = 83 DEC.
The only task is to get the digits of a number and not to do any obscure number conversions. So 000123 gets [0, 0, 0, 1, 2, 3]. No one else on the page misunderstood this task.
S
Siva

Easier way I think is to convert the number to string and use substring to extract and then convert to integer.

Something like this:

int digits1 =Integer.parseInt( String.valueOf(201432014).substring(0,4));
    System.out.println("digits are: "+digits1);

ouput is 2014


does type conversion here will cost more or division operations?
F
Flexo

I wrote a program that demonstrates how to separate the digits of an integer using a more simple and understandable approach that does not involve arrays, recursions, and all that fancy schmancy. Here is my code:

int year = sc.nextInt(), temp = year, count = 0;

while (temp>0)
{
  count++;
  temp = temp / 10;
}

double num = Math.pow(10, count-1);
int i = (int)num;

for (;i>0;i/=10)
{
  System.out.println(year/i%10);
}

Suppose your input is the integer 123, the resulting output will be as follows:

1
2
3

p
parsecer

Here is my answer, I did it for myself and I hope it's simple enough for those who don't want to use the String approach or need a more math-y solution:

public static void reverseNumber2(int number) {

    int residual=0;
    residual=number%10;
    System.out.println(residual);

    while (residual!=number)  {
          number=(number-residual)/10;
          residual=number%10;
          System.out.println(residual);
    }
}

So I just get the units, print them out, substract them from the number, then divide that number by 10 - which is always without any floating stuff, since units are gone, repeat.


q
qben

Java 8 solution to get digits as int[] from an integer that you have as a String:

int[] digits = intAsString.chars().map(i -> i - '0').toArray();

Instead of using i - '0' there is also methods like Character.toDigit that IMO are better to use.
@SimonForsberg can you reference the method in the docs and give a code snippet how that would work? I'm happy to update my answer if there's a more elegant way.
@qben "0123456789".chars().map(i -> Character.digit(i, 10)).toArray() Character#digit (there's one for char and one for int codePoints)
W
WesternGun

Why don't you do:

String number = String.valueOf(input);
char[] digits = number.toCharArray();

A
Ankit Kumar Rajpoot

Try this one.

const check = (num) => {
  let temp = num
  let result = []
  while(temp > 0){
    let a = temp%10;
    result.push(a);
    temp = (temp-a)/10;
  }
  return result;
}

check(98) //[ 8, 9 ]

K
Kaplan

neither chars() nor codePoints() — the other lambda

String number = Integer.toString( 1100 );

IntStream.range( 0, number.length() ).map( i -> Character.digit( number.codePointAt( i ), 10 ) ).toArray();  // [1, 1, 0, 0]

D
Don Branson

Integer.toString(1100) gives you the integer as a string. Integer.toString(1100).getBytes() to get an array of bytes of the individual digits.

Edit:

You can convert the character digits into numeric digits, thus:

  String string = Integer.toString(1234);
  int[] digits = new int[string.length()];

  for(int i = 0; i<string.length(); ++i){
    digits[i] = Integer.parseInt(string.substring(i, i+1));
  }
  System.out.println("digits:" + Arrays.toString(digits));

This is slightly misleading. This will give you an array of bytes representing the char '1' or '0'. The byte values wont be 1, or 0.
Misleading? That's a little harsh. The question was ambiguous. It really depends what he wants to do with the digits. You're assuming that he wants to perform calculations. My answer assumes text processing. Either assumption is partially correct, but it was not my intent to mislead.
I guess I feel it is misleading because you get an array of bytes, which I think of numbers not characters.
@Justin - Ah, okay. I don't automatically associate bytes as not characters. In my assembly days, I'd increment 'a' to get 'b', iterating through the alphabet - so sometimes bytes were simultaneously both. Of course, high-level languages and UTF render that all moot.
S
Simple Sandman

This uses the modulo 10 method to figure out each digit in a number greater than 0, then this will reverse the order of the array. This is assuming you are not using "0" as a starting digit.

This is modified to take in user input. This array is originally inserted backwards, so I had to use the Collections.reverse() call to put it back into the user's order.

    Scanner scanNumber = new Scanner(System.in);
    int userNum = scanNumber.nextInt(); // user's number

    // divides each digit into its own element within an array
    List<Integer> checkUserNum = new ArrayList<Integer>();
    while(userNum > 0) {
        checkUserNum.add(userNum % 10);
        userNum /= 10;
    }

    Collections.reverse(checkUserNum); // reverses the order of the array

    System.out.print(checkUserNum);

j
jmarcosSF

Just to build on the subject, here's how to confirm that the number is a palindromic integer in Java:

public static boolean isPalindrome(int input) {
List<Integer> intArr = new ArrayList();
int procInt = input;

int i = 0;
while(procInt > 0) {
    intArr.add(procInt%10);
    procInt = procInt/10;
    i++;
}

int y = 0;
int tmp = 0;
int count = 0;
for(int j:intArr) {
    if(j == 0 && count == 0) {
    break;
    }

    tmp = j + (tmp*10);
    count++;
}

if(input != tmp)
    return false;

return true;
}

I'm sure I can simplify this algo further. Yet, this is where I am. And it has worked under all of my test cases.

I hope this helps someone.


A
Akbarsha
int number = 12344444; // or it Could be any valid number

int temp = 0;
int divider = 1;

for(int i =1; i< String.valueOf(number).length();i++)
 {

    divider = divider * 10;

}

while (divider >0) {

    temp = number / divider;
    number = number % divider;
    System.out.print(temp +" ");
    divider = divider/10;
}

12344444 is to big to be an int.
@Beppe 12344444 is not too big to be an int. Java docs claims the following For int, from -2147483648 to 2147483647, inclusive Though to know for sure on your system you could use System.out.println(Integer.MAX_VALUE); to find out the max_value that is supported in your java.lang package
y
yanisB

Try this:

int num= 4321
int first  =  num % 10;
int second =  ( num - first ) % 100 / 10;
int third  =  ( num - first - second ) % 1000 / 100;
int fourth =  ( num - first - second - third ) % 10000 / 1000;

You will get first = 1, second = 2, third = 3 and fourth = 4 ....


This is less utilitarian and elegant than the general methods listed above, nor is it different in principle than other answers using %. It adds little value.
@Shawn Mehan, I would disagree. The methods above are mostly about using String or about long multi-lined solutions, while this one is plain and simple.
This doesn't support any number of digits in the number but relies on copy-pasting and modifying assignments which is very error-prone since it's easy to make mistakes.
S
Shibashis
public int[] getDigitsOfANumber(int number) {
    String numStr = String.valueOf(number);
    int retArr[] = new int[numStr.length()];

    for (int i = 0; i < numStr.length(); i++) {
        char c = numStr.charAt(i);
        int digit = c;
        int zero = (char) '0';
        retArr[i] = digit - zero;

    }
    return retArr;
}

Please update your answer and explain how it resolves the problem. Code-only responses are generally considered to be poor quality answers.
P
Pritam Banerjee

Something like this will return the char[]:

public static char[] getTheDigits(int value){
    String str = "";
    int number = value;
    int digit = 0;
    while(number>0){
        digit = number%10;
        str = str + digit;
        System.out.println("Digit:" + digit);
        number = number/10;     

    }
    return str.toCharArray();
}

A
Akenaten

As a noob, my answer would be:

String number = String.valueOf(ScannerObjectName.nextInt()); 
int[] digits = new int[number.length()]; 
for (int i = 0 ; i < number.length() ; i++)
    int[i] = Integer.parseInt(digits.substring(i,i+1))

Now all the digits are contained in the "digits" array.


K
Kaplan

if digit is meant to be a Character

String numstr = Integer.toString( 123 );
Pattern.compile( "" ).splitAsStream( numstr ).map(
  s -> s.charAt( 0 ) ).toArray( Character[]::new );  // [1, 2, 3]

and the following works correctly
numstr = "000123" gets [0, 0, 0, 1, 2, 3]
numstr = "-123"    gets [-, 1, 2, 3]


Pattern.compile ? That's a lot of overkill.
@Simon-Forsberg At the time of writing this was the only solution that created a Character-array. I doubt that a single call to Pattern.compile is more time-consuming than repeatedly calling the modulo operator % and it can process all large numbers (no int-type-limitation) at the same time.
R
Ragowit

A .NET solution using LINQ.

List<int> numbers = number.ToString().Select(x => x - 48).ToList();

r
ramazan polat

I think this will be the most useful way to get digits:

public int[] getDigitsOf(int num)
{        
    int digitCount = Integer.toString(num).length();

    if (num < 0) 
        digitCount--;           

    int[] result = new int[digitCount];

    while (digitCount-- >0) {
        result[digitCount] = num % 10;
        num /= 10;
    }        
    return result;
}

Then you can get digits in a simple way:

int number = 12345;
int[] digits = getDigitsOf(number);

for (int i = 0; i < digits.length; i++) {
    System.out.println(digits[i]);
}

or more simply:

int number = 12345;
for (int i = 0; i < getDigitsOf(number).length; i++) {
    System.out.println(  getDigitsOf(number)[i]  );
}

Notice the last method calls getDigitsOf method too much time. So it will be slower. You should create an int array and then call the getDigitsOf method once, just like in second code block.

In the following code, you can reverse to process. This code puts all digits together to make the number:

public int digitsToInt(int[] digits)
{
    int digitCount = digits.length;
    int result = 0;

    for (int i = 0; i < digitCount; i++) {
        result = result * 10;
        result += digits[i];
    }

    return result;
}

Both methods I have provided works for negative numbers too.


S
SocketM

see bellow my proposal with comments

          int size=i.toString().length(); // the length of the integer (i) we need to split;
           ArrayList<Integer> li = new ArrayList<Integer>(); // an ArrayList in whcih to store the resulting digits

        Boolean b=true; // control variable for the loop in which we will reatrive step by step the digits
        String number="1"; // here we will add the leading zero depending on the size of i
        int temp;  // the resulting digit will be kept by this temp variable

    for (int j=0; j<size; j++){
                        number=number.concat("0");
                    }

Integer multi = Integer.valueOf(number); // the variable used for dividing step by step the number we received 
                while(b){

                    multi=multi/10;
                    temp=i/(multi);
                    li.add(temp);
                    i=i%(multi);
                                        if(i==0){
                                        b=false;
                                        }


                }

                for(Integer in: li){
                    System.out.print(in.intValue()+ " ");
                }

a
always007
import java.util.Scanner;

class  Test 
{  
    public static void main(String[] args)   
    {  
        Scanner sc = new Scanner(System.in); 


    int num=sc.nextInt(); 
    System.out.println("Enter a number (-1 to end):"+num);
    int result=0;
    int i=0;
    while(true) 
    { 
      int n=num%10;
      if(n==-1){
        break;
      }
      i++;
      System.out.println("Digit"+i+" = "+n);
      result=result*10+n;
      num=num/10; 


      if(num==0) 
      { 
        break; 
      } 
    }
    }
}