Возвращает первую цифру целого числа

Как в Java вы возвращаете первую цифру целого числа?

i.e.

345

Возвращает целое число 3.


person Tony    schedule 12.01.2010    source источник
comment
Без строки вы можете извлечь ее, используя операцию по модулю. (345/10)%10 = 4 , (345/100)%10 = 5   -  person Aven Desta    schedule 30.03.2021


Ответы (20)


Самый простой способ — использовать String.valueOf(Math.abs((long)x)).charAt(0) — это даст вам char1. Чтобы получить это как целочисленное значение, вы можете просто вычесть «0» (как в Unicode, от «0» до «9» являются смежными).

Это несколько расточительно, конечно. Альтернативой было бы просто взять абсолютное значение, а затем циклически делить на 10, пока число не окажется в диапазоне 0-9. Если это домашнее задание, я бы дал такой ответ. Однако я не буду приводить для него код, потому что думаю, что это может быть домашним заданием. Однако, если вы предоставите комментарии и отредактируете свой ответ, чтобы объяснить, как у вас дела и с какими проблемами вы сталкиваетесь, мы можем помочь.


1Обратите внимание, что абсолютное значение Integer.MIN_VALUE не может быть представлено как int, поэтому вы можете сначала преобразовать его в long, затем использовать Math.abs, затем заниматься арифметикой. Вот почему там есть актерский состав.

person Jon Skeet    schedule 12.01.2010
comment
Мне не нравится, что это решение включает преобразование числа в строку, но мне нравится тот факт, что это однострочник, вы получили мой голос. - person monksy; 12.01.2010
comment
Это будет около «0». Не работает для Integer.MIN_VALUE. - person Tom Hawtin - tackline; 12.01.2010
comment
(1String.valueOf(-Math.abs(x)).charAt(1)` ? Или это немного непонятно?) - person Tom Hawtin - tackline; 12.01.2010
comment
@Tom: я как раз редактировал проблему Integer.MIN_VALUE. Работа с длинными упрощается :) Не уверен, что вы имеете в виду, говоря, что это «0», учитывая второе предложение моего первого абзаца. Не очевидно, хочет ли ОП символ или целое число. - person Jon Skeet; 12.01.2010
comment
@Jon Skeet: Вы начинаете с самого простого способа, а затем переходите к объединению 4 функций и 2 приведений с инструкциями для дальнейшей обработки. Само по себе это неплохое решение, но я не могу согласиться с нелепым количеством голосов, которые вы получаете за это византийское изобретение. - person Carl Smotricz; 12.01.2010
comment
@Carl: Там есть только одно приведение (к long) и три вызова метода (valueOf, abs, charAt). Предложение зацикливания во второй форме по-прежнему требует приведения (или неявного преобразования) и abs, чтобы справиться с Integer.MIN_VALUE. Я тоже не согласен с тем, что это византийское — мне это кажется совершенно естественным. Целое число действительно имеет только первую цифру, если рассматривать его в форматированном смысле, поэтому преобразование его в строку и получение первого символа довольно очевидно, не так ли? Другие сложности связаны только с тем, чтобы справиться с отрицательными числами. - person Jon Skeet; 12.01.2010
comment
@Jon Skeet: я просчитался, и избиратели явно на вашей стороне. - person Carl Smotricz; 12.01.2010
comment
@Carl: Это, конечно, не делает избирателей правыми :) Я, конечно, не хотел бы отвлекать вас от критики... что не то же самое, что обещать, что я не буду защищать свои решения :) (Как много минусов можно вставить в предложение?) - person Jon Skeet; 12.01.2010
comment
@Jon: Это зависит от того, сколько вызовов функций вы можете поместить в одну строку? ;) А если серьезно, я думаю, что вы слишком усердно работаете, чтобы уловить крайние случаи в плохо определенном домашнем задании. Тем не менее, это правильное решение, поэтому, если вы отредактируете свой ответ, я отзову свой голос. - person Carl Smotricz; 12.01.2010
comment
Тем не менее, еще один удар по вашему решению: это совершенно неуместно в качестве решения проблемы с домашним заданием. Как он когда-нибудь объяснит этот код своему учителю? ;) - person Carl Smotricz; 12.01.2010
comment
@Карл: отредактировано. Заставить его работать вообще было для ОП. Разработка угловых случаев была для меня :) - person Jon Skeet; 12.01.2010
comment
Другая вещь, которую вы могли бы сделать, предполагая, что нас не волнуют создаваемые объекты, это String.valueOf(BigInteger.valueOf(x).abs()).charAt(0) - person Paul Wagland; 13.01.2010
comment
+1 - Я работаю над библиотекой утилит String, которые я часто использую, и я использую это для преобразования чисел из формы int в их «имя». Бывший. 9123 -> девять тысяч сто двадцать три. Это немного поможет. Спасибо! Кстати, да, я только что использовал обе вещи, которых следует избегать в этом комментарии. - person Fund Monica's Lawsuit; 23.12.2013

Еще один способ:

public int firstDigit(int x) {
  if (x == 0) return 0;
  x = Math.abs(x);
  return (int) Math.floor(x / Math.pow(10, Math.floor(Math.log10(x))));
}
person liwp    schedule 12.01.2010
comment
Мне было бы интересно узнать, правильно ли это работает для каждого целого числа. Я был бы обеспокоен неточностями с плавающей запятой, но это может быть хорошо. Трудно эффективно тестировать... - person Jon Skeet; 12.01.2010
comment
Интересно, что это решение дает тот же результат, что и мое, для всех целых чисел от 0 до 100 000 000. Тем не менее, это не делает негатива. - person Carl Smotricz; 12.01.2010
comment
Требуются небольшие изменения, чтобы вернуть 0, если x == 0, и firstDigit(-x), если x ‹ 0. - person lins314159; 13.01.2010
comment
@lins314159: спасибо, я добавил проверки для них @Jon: я подумал, что протестирую алгоритм с библиотекой Haskell QuickCheck, и результаты интересны: когда я запускаю тест в интерактивном режиме, он проходит, когда я компилирую тестовый код, он терпит неудачу - 1000, 1000. Оказывается, log 1000 возвращает 2,999... в скомпилированном коде, а не 3. Это именно та ошибка с плавающей запятой, о которой вы беспокоились. Однако в Java этого не происходит (по крайней мере, с теми же значениями). Я посмотрю, что скажет список рассылки haskell. - person liwp; 13.01.2010
comment
divisor = (int)(Math.pow(10,(int) Math.log10(rem))); первая цифра = (целое число) (рем * 1,0 / делитель); - person srikanth Nutigattu; 10.05.2020

public static int firstDigit(int n) {
  while (n < -9 || 9 < n) n /= 10;
  return Math.abs(n);
}

Должен также хорошо обрабатывать отрицательные числа. В этом случае вернет отрицательную первую цифру.

person Carl Smotricz    schedule 12.01.2010
comment
String generalSolution = carlsSolution.replace(345, Math.abs(inputValue)); - person Andreas Dolk; 12.01.2010
comment
@Andreas_D: Я только что понял, что, возможно, мне не хватало голосов, потому что люди не могли совершить этот интеллектуальный скачок, поэтому я сделал это явной функцией. - person Carl Smotricz; 12.01.2010
comment
@Gennadiy Геннадий, мне жаль, что я отредактировал свое решение, так как вы оставили свой комментарий, но и раньше оно не было неправильным. Любое целочисленное значение, квадрат которого больше 81, имеет абсолютное значение больше 9, и, поскольку это целое число, это означает, что оно не менее 10. - person Carl Smotricz; 12.01.2010
comment
@Tom: в спецификации не сказано, что делать с отрицательными числами. Разрешены ли отрицательные входы? Они буквально хотят первую цифру или им нужен первый символ ( - )? Я не хочу слишком сильно беспокоиться об этом. - person Carl Smotricz; 12.01.2010

Игнорирование отрицательных значений приводит к:

(""+345).charAt(0);
person stacker    schedule 12.01.2010

Отсутствующее рекурсивное решение:

int getFirstInt(int input) {
  if (input > 0 ? input < 10 : input > -10) {
    return input > 0 ? input : -input;
  }
  return getFirstInt(input / 10);
}

Я бы не стал использовать тернарный оператор в реальной жизни, но — разве это не красиво? ;)

person Andreas Dolk    schedule 12.01.2010
comment
Не справляется с Integer.MIN_VALUE, но приятно видеть рекурсивную версию. Я не думаю, что стал бы использовать условный оператор для условия if, но я мог бы использовать его для оператора return - по крайней мере, если бы Math.abs не существовало. - person Jon Skeet; 12.01.2010
comment
@Jon, раньше тестировал его с Integer.MIN_VALUE, и результат был «2», с приведением к long и без него ... Это действительно проблема? - person Andreas Dolk; 13.01.2010
comment
Это не будет проблемой, поскольку вы никогда не пытаетесь отрицать MIN_VALUE, а только когда-либо пытаетесь отрицать значения от -1 до -9, они (очевидно) имеют положительные эквиваленты. - person Paul Wagland; 13.01.2010

Я нахожу это более простым:

int firstDigit(int num)
{
    if(num/10 == 0)
        return num;
    return firstDigit(num/10);

}
  • Ввод: 123 => Вывод: 1
  • Ввод: -123 => Вывод: -1
person Aiden    schedule 06.04.2015

Обновлено: решение log10:

Вариант решения log10 без деления:

public int getFirstDigit(int x) {
    double e = Math.log10(Math.abs((long) x));
    return Double.valueOf(Math.pow(10.0, e - Math.floor(e))).intValue());
}

Что он делает?

  1. приведите целое к длинному (чтобы справиться с проблемой MIN_VALUE)
  2. получить абсолютное значение
  3. рассчитать лог10
  4. рассчитать пол из бревна10
  5. вычесть пол из бревна10 (разница будет дробью)
  6. поднимите десять до разницы, давая вам значение первой цифры.

Решение цикла while:

Чтобы обработать Integer.MIN_VALUE и сохранить Math.abs() и приведение к длинному циклу:

public static int getFirstDigit(int i) {
    i = Math.abs(i / (Math.abs((long)i) >= 10 ) ? 10 : 1);
    while (i >= 10 ) 
        i /= 10;
    return i;
}
person Matthew Flynn    schedule 12.01.2010

Самый быстрый способ:

  • Вычислите журнал abs(x), затем получите пол. Назовем это н.
  • Разделите число на 10^n
person fastcodejava    schedule 12.01.2010
comment
Насколько вы уверены, что вычисление журнала и вычисление степени, а затем однократное деление будет быстрее, чем выполнение до 9 целочисленных делений на 10? Честно говоря, я бы не хотел об этом догадываться... или утверждать, что это универсально верно для всех процессоров и JVM. - person Jon Skeet; 12.01.2010
comment
Я немного в шоке от этого, но оказалось, что решение liwp, очень похожее на это, возвращает правильный результат на большей части своего диапазона (я сдался после 100 миллионов). Это удача или эти трансцендентные функции очень поддаются именно этой проблеме, или что?? Справедливости ради, +1 и здесь. - person Carl Smotricz; 13.01.2010
comment
Что касается производительности... да. Вероятно, они не будут запускать этот алгоритм ни в одном суперкомпьютерном центре. Это имеет значение? ;) - person Carl Smotricz; 13.01.2010

Подсказка к домашнему заданию: преобразовать его в строку и вернуть первый символ.

person George Johnston    schedule 12.01.2010
comment
Итак, возьмите абсолютное значение, затем приведите его к строке, а затем верните первый символ. - person George Johnston; 12.01.2010

Глядя на предоставленный код, кажется, что все это немного усложняет, вот простое решение...

int number = 4085;
int firstDigit = number;
while (firstDigit > 9)
{
      firstDigit = firstDigit / 10;
}
System.out.println("The First Digit is " + firstDigit);
person Tristan Angel    schedule 11.11.2012

Предположим, что число имеет тип int

поэтому,

int number = 352
// Change the int into String format
String numberString = Integer.toString(number);
// We can know the first digit of that String with substring method directly
Integer.parseInt(numberString.substring(0,1));

или другой способ - изменить строку на char и получить числовое значение из char

e.g.

int number = 352;
String numberString = Integer.toString(number);
Character.getNumericValue(String.valueOf(target).charAt(0)); 
// 0 means the first digit of the number
person Yu Wei Chen    schedule 01.09.2017

Я думаю, что это может быть хорошим способом сделать это:

public static int length(int number) {
    return (int)Math.log10(Math.abs(number)) + 1;
}

public static int digit(int number, int digit) {
    for (int i = 0; i < digit; i++) {
        number /= 10;
    }
    return Math.abs(number % 10);
}

Работает как для отрицательных, так и для положительных чисел. digit(345, length(345) - 1) вернет 3, digit(345, 0) вернет 5, например. и так далее...

person borchero    schedule 13.06.2015

public static void firstDigit(int number){      
    while(number != 0){
        if (number < 10){
            System.out.println("The first digit is " + number);
        }
            number = number/10;

        }
    }

Когда вы вызываете его, вы можете использовать Maths.abs, чтобы он работал с отрицательным числом:

firstDigit(Math.abs(9584578)); 

Это возвращает 9

person alex    schedule 26.01.2018

Это Groovy, но его легко преобразовать в Java:

int firstNum(int x) {
    a = Math.abs(x)
    sig = Math.floor(Math.log10(a))
    return a / Math.pow(10, sig)
}

Полученные результаты:

заводной> println(firstNum(345))
3

заводной> println(firstNum(3452))
3

заводной> println(firstNum(-112))
1

заводной> println(firstNum(9999))
9

groovy> println(firstNum(Integer.MAX_VALUE))
2

groovy> println(firstNum(Integer.MIN_VALUE + 1))
2

person matt b    schedule 12.01.2010

Вот чрезвычайно простой способ получения первой и второй цифр целого числа по отдельности, но он будет работать только для ровно двух цифр!

    int firstDigit = number / 10;
    int secondDigit = number % 10;

В ситуации, когда пользователь может ввести больше или меньше цифр, но вы можете не знать, сколько их, вы можете попробовать этот подход, но другие ответы имеют лучшие решения для этого случая. Я только что написал эту полную программу, которую вы можете вставить в компилятор и запустить. Как только вы увидите шаблон, вы можете проверить столько цифр, сколько хотите, а затем просто поймать длину, большую, чем вы хотите принять:

package testingdigits;

import java.util.Scanner;

public class TestingDigits {


Scanner keyboard = new Scanner(System.in);    

public static void main(String[] args) 
{

Scanner keyboard = new Scanner(System.in);

System.out.printf("\nEnter a number to test:");
int number = keyboard.nextInt();

int length = (int) Math.log10(number) + 1; //This gets the length of the number of digits used 

//Initializing variables first to prevent error
int firstDigit = 0, secondDigit = 0, thirdDigit = 0, fourthDigit = 0, fifthDigit = 0, sixthDigit = 0;

    if (length == 1)
     {
        firstDigit = number;
        System.out.println("" + firstDigit);
     }
    if (length == 2)
     {
        firstDigit = number / 10; //For example, 89/10 will output 8.9 and show as 8 in this case.
        secondDigit = number % 10;
        System.out.println("" + firstDigit + "" + secondDigit);
     }
    if (length == 3)
     {
        firstDigit = number / 10 / 10; // 123/10/10 is 1.23 and will show as 1
        secondDigit = number / 10 % 10;
        thirdDigit = number % 10;
        System.out.println("" + firstDigit + "" + secondDigit + "" + thirdDigit);
     }
    if (length == 4)
     {
        firstDigit = number / 10 / 10 / 10; 
        secondDigit = number / 10 / 10 % 10;
        thirdDigit = number / 10 % 10;
        fourthDigit = number % 10;
        System.out.println("" + firstDigit + "" + secondDigit + "" + thirdDigit + "" + fourthDigit);
     }
     if (length == 5)
     {
        firstDigit = number / 10 / 10 / 10 / 10; 
        secondDigit = number / 10 / 10 / 10 % 10;
        thirdDigit = number / 10 / 10 % 10;
        fourthDigit = number / 10 % 10;
        fifthDigit = number % 10;
        System.out.println("" + firstDigit + "" + secondDigit + "" + thirdDigit + "" + fourthDigit + "" + fifthDigit);
     }
    //You can probably see the pattern by now. It's not an elegant solution, but is very readable by even beginners:     
    if ((length == 6))
     {
        firstDigit = number / 10 / 10 / 10 / 10 / 10; //The first digit is divided by 10 for however many digits are after it
        secondDigit = number / 10 / 10 / 10 % 10;
        thirdDigit = number / 10 / 10 / 10 % 10;
        fourthDigit = number / 10 / 10 % 10;
        fifthDigit = number / 10 % 10; //The second to last always looks like this
        sixthDigit = number % 10;  //The last digit always looks like this no matter how big you go
        System.out.println("" + firstDigit + "" + secondDigit + "" + thirdDigit + "" + fourthDigit + "" + fifthDigit + "" + sixthDigit);
     }
    if ((length > 6))
     {
        //The main problem with this approach is that you have to define in advance how many digits you are working with
        //So it's simple, but not very elegant, and requires something to catch unexpected input from the user.
        System.out.println("Invalid Input!");
     }

  }

}

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

Кроме того: в случае, когда вы начинаете с двойного числа, вы можете использовать следующее для преобразования в int и усечения десятичных знаков:

numberInt = (int)number;
person Elliander    schedule 10.07.2015

Вот уменьшенная версия для получения цифр всех позиций, она работает с отрицательным значением (не десятичным).

int number = -23456;

int length = (int) Math.log10(Math.abs(number)) + 1; //This gets the length of the number of digits used
//Math.abs to change negative int to positive

System.out.println("Digit at pos " + 1 + " is :- " + (int)(Math.abs(number)/Math.pow(10,(length-1))));

for (int i = 2; i <= length; i++){
    System.out.println("Digit at pos " + i + " is :- " + (int)(Math.abs(number)/Math.pow(10,(length-i))%10));
}
person Abdullah Salem    schedule 17.01.2018

Чтобы разделить цифры целого числа слева направо, я использую 2 разных метода: первый для подсчета количества цифр, из которых состоит целое число, а затем я разделяю их слева направо, разделив целое число на 10, возведенное в степень количество цифр минус 1.

//method to separate digits of an integer from left to right
private static void separateDigits(int num){
    int numOfDigits = countNumberOfDigits(num);
    for (int numOfZeros = numOfDigits-1; numOfZeros >= 0 ; --numOfZeros){
        int divisor = (int) Math.pow(10, numOfZeros);
        System.out.print( Math.abs(num) / divisor + " // " );
        num %= divisor;
    }
}

//method to count number of digits
private static int countNumberOfDigits(int num){
    int numOfDigits=0;
    //using absolute value of num allows method to work even with negative integers
    while(Math.abs(num) > 0){ 
        num = num / 10;
        numOfDigits++; //this counts the number of times the "while" loops
    }
    return numOfDigits;
}

Никакого использования массивов или рекурсивных методов, просто деление с помощью «/» и «%».

Вызов метода:

public static void main(String args[]) {

separateDigits( -123456789 );

}

выходы: 1 // 2 // 3 // 4 // 5 // 6 // 7 // 8 // 9 //

person Eliau Maimon    schedule 11.05.2018

Я думаю проще сделать:

int firstDigit = i-(i/10)*10 // i is an integer or long value, positive or negative.
person Bruno L.    schedule 03.10.2018
comment
Я думаю, что если вы проверите это на 123, вы получите 3, а не 1. - person Larry Engholm; 01.04.2019
comment
Нет, сэр... 123 - 120 = 3 - person Bruno L.; 04.04.2019
comment
Спасибо, что подтвердили это. Я считаю, что первая цифра 123 равна 1. - person Larry Engholm; 05.04.2019

Этот способ отлично сработал для меня, но он включает преобразование из int в строку и обратно в int.

Integer.parseInt(String.valueOf(x).substring(0,1));
person The Halfling    schedule 11.01.2018
comment
что произойдет, если он будет отрицательным? - person King Midas; 11.01.2018
comment
Чтобы это работало правильно, вы должны добавить вызов Abs: Integer.parseInt(String.valueOf(Math.abs(x)).substring(0,1)); - person Anton Gorbunov; 11.01.2018
comment
В порядке. К счастью, в моем приложении будут только положительные целые числа, но я все же внесу это изменение. Спасибо! - person The Halfling; 12.01.2018

person    schedule
comment
если число отрицательное, Math.Abs() сначала, естественно. - person Terje; 13.01.2010