- Проверить положительный или отрицательный без использования условных операторов в Java
- 8 ответов
- Java – проверьте, является ли ввод положительным целым числом, отрицательным целым числом, натуральным числом и т.д.
- Проверка правильности ввода с использованием java.util.Scanner [duplicate]
- 6 ответов
- Обзор методов Scanner.hasNextXXX
- Пример 1: Проверка положительных целых чисел
- Ссылки API
- Связанные вопросы
- Ссылки
- Пример 4. Использование двух Scanner сразу
- Резюме
Проверить положительный или отрицательный без использования условных операторов в Java
Вопрос интервью, который мне задавали на прошлой неделе:
Мне нужна функция, чтобы распечатать, является ли число положительным или отрицательным без использования условных операторов, таких как if else while for switch a? b:c и т.д. Как я могу это сделать.
Я сказал интервьюеру, что это невозможно, потому что вопрос носит «условный» характер. Он сказал мне, что это возможно, но не сказал мне, как. Я довольно много искал, но не получил хороших ответов.
8 ответов
Одно из возможных решений:
String[] responses = ; System.out.println(responses[(i >> 31) & 1]);
Это также считает ноль как положительное число.
Поскольку целые числа в Java должны храниться в дополнении к двум (или вести себя так, как будто они есть), старший бит любого отрицательного числа равен 1, а старший бит любого другого числа равен 0. (i >> 31) копирует старший бит в каждый второй бит (поэтому отрицательные числа становятся 11111111 11111111 11111111 11111111 и положительные / нулевые числа становятся 00000000 00000000 00000000 00000000 ). & 1 устанавливает все, кроме младшего бита, в 0. Комбинация (i >> 31) & 1 эффективно читает только самый высокий бит i ,
Просто, чтобы уточнить ответ imibis немного:
int index(int i) < return 1 + (i>>31) - (-i>>31); > String[] text = ; private String text(int i)
Подписанная смена i>>31 конвертирует каждое отрицательное число в -1 и каждый другой в 0 , вычисления -i>>31 позволяет отличить положительные числа от неположительных. Теперь посмотрим на вычисленные index :
positive: 1 + 0 - (-1) = 2 zero: 1 + 0 - 0 = 1 negative: 1 + (-1) - 0 = 0
Вот вариант, учитывающий тот факт, что ноль не является ни положительным, ни отрицательным:
int x = (int)Math.sqrt(Math.pow(n, 2)); try < x = n / x; >catch (ArithmeticException e) < x = 0; >String[] result = ; System.out.println(result[x + 1]);
Супер простое решение, использующее тот факт, что массивы не могут иметь отрицательный размер:
void printPositive(int i) < try < new int[i]; System.out.println("positive"); >catch( NegativeArraySizeException e) < System.out.println("negative"); >>
Хорошо, этот ответ может выделить огромный массив, если i положительно, и виртуальная машина может использовать условные выражения при оценке new int[i] Но, по крайней мере, это показало бы интервьюеру какое-то творчество. Кроме того, это может показать интервьюеру, что вы можете думать нестандартно (потому что он может ожидать, что вы сделаете немного магии, как и большинство других ответов), и сделать что-то совершенно другое.
Старый ответ Причина, по которой я делаю этот новый ответ, заключается в том, что я использовал логическое compareTo метод, который использует троичный оператор для преобразования логических выражений в двоичный файл.
Вот мой новый ответ, который гораздо более нечитабелен.
public static String positiveOrNegative(int n) < ArrayListresponses = new ArrayList(); // first element should be "Zero", so if n is 0, the response is "Zero" responses.add("Zero"); // this populates the ArrayList with elements "Positive" for n elements // so that if n is positive, n will be an index in the ArrayList // and the return will be "Positive" // but still if n is negative, it will never be an index in the ArrayList for (int i = 0; i < n; i++) < responses.add("Positive"); >String response = ""; try < // try to get a response from the ArrayList response = responses.get(n); >catch (Exception e) < // index is out of bounds, so it must have been negative response = "Negative"; >return response; > public static void main(String[] args) < System.out.println(positiveOrNegative(4)); // Positive System.out.println(positiveOrNegative(1)); // Positive System.out.println(positiveOrNegative(0)); // Zero System.out.println(positiveOrNegative(-1)); // Negative System.out.println(positiveOrNegative(-4)); // Negative >
Java – проверьте, является ли ввод положительным целым числом, отрицательным целым числом, натуральным числом и т.д.
Есть ли встроенный метод в Java, где вы можете найти тип ввода пользователя, является ли он положительным или отрицательным, и так далее? Код ниже не работает. Я пытаюсь найти способ ввода любого встроенного метода, который может сделать это в выражении if.
import java.util.Scanner; public class Compare < public static void main(String[] args) < Scanner input = new Scanner(System.in); System.out.print("Enter a number: "); int number = input.nextInt(); if(number == int) System.out.println("Number is natural and positive."); >>
Если вам действительно нужно избегать операторов, используйте Math.signum()
Возвращает функцию signum аргумента; ноль, если аргумент ноль, 1,0, если аргумент больше нуля, -1.0, если аргумент меньше нуля.
ОБНОВЛЕНИЕ: Согласно комментариям, это работает только для двойных и плавающих значений. Для целочисленных значений вы можете использовать метод:
Как использовать следующие функции:
int number = input.nextInt(); if (number < 0) < // negative >else < // it a positive >
(Вы должны как оператор Else-If проверить для трех разных состояний (положительный, отрицательный, 0)
Вот простой пример (исключая возможность нецелых значений)
import java.util.Scanner; public class Compare < public static void main(String[] args) < Scanner input = new Scanner(System.in); System.out.print("Enter a number: "); int number = input.nextInt(); if( number == 0) < System.out.println("Number is equal to zero"); >else if (number > 0) < System.out.println("Number is positive"); >else < System.out.println("Number is negative"); >> >
Для целых чисел вы можете использовать Integer.signum()
Возвращает функцию signum указанного значения int. (Возвращаемое значение равно -1, если указанное значение отрицательное; 0, если указанное значение равно нулю; и 1, если указанное значение положительное.)
Вы можете использовать if(number >= 0) . Тот факт, что вы используете int number = input.nextInt(); , гарантирует, что он должен быть целым.
Проверка правильности ввода с использованием java.util.Scanner [duplicate]
Многие из ваших вопросов находятся в такой форме: недобросовестные просьбы о том, чтобы кто-то другой опубликовал код, а вы не показали, что вы сделали (или попробовали) самостоятельно. Это не способ изучать новые вещи. Грязная рука! Попробуйте несколько вещей сами и, если вы застряли где-нибудь, опубликуйте здесь конкретный вопрос (и напишите код, который не работал). Уверяю вас, что таким образом вы получите лучшие ответы, чем эти близкие голоса.
@Bart Барт К: было бы справедливо по отношению к другим ответчикам, если, пытаясь улучшить вопрос, чтобы сделать его достойным повторного открытия, я отредактирую его, чтобы спросить, как проверить входные данные с помощью Scanner ? Исходя из предыдущего Q OP, кажется, что Scanner — это то, с чем OP работает.
@polygenelubricants, да, я бы проголосовал, чтобы вновь открыть, если вопрос будет перефразирован, чтобы он имел больше смысла. Было бы обидно, если этот вопрос будет удален в долгосрочной перспективе (и все хорошие ответы с ним (в основном, ваш)). Конечно, я надеялась, что @bhavna попыталась бы улучшить его сам или сама .
@Bart Барт К: редактирование завершено. Также улучшит мой ответ еще дальше. Извиняюсь перед другими ответчиками, если они считают, что это несправедливо.
6 ответов
Обзор методов Scanner.hasNextXXX
java.util.Scanner имеет много методов hasNextXXX , которые могут использоваться для проверки ввода. Вот краткий обзор всех из них:
- hasNext() — у него есть любой токен вообще?
- hasNextLine() — есть ли еще одна строка ввода?
- Для Java-примитивов
- hasNextInt() — у него есть токен, который можно разобрать в int ?
- Также доступны hasNextDouble() , hasNextFloat() , hasNextByte() , hasNextShort() , hasNextLong() и hasNextBoolean()
- В качестве бонуса также есть hasNextBigInteger() и hasNextBigDecimal()
- Интегральные типы также имеют перегрузки для указания оснований (например, шестнадцатеричных)
- hasNext(String pattern)
- hasNext(Pattern pattern) — это Pattern.compile перегрузка
Scanner способен к большему, включенному тем, что он основан на регулярном выражении. Важной особенностью является useDelimiter(String pattern) , которая позволяет определить, какой шаблон разделяет ваши токены. Существуют также методы find и skip , которые игнорируют разделители.
Следующее обсуждение будет поддерживать регулярное выражение как можно более простым, поэтому фокус остается на Scanner .
Пример 1: Проверка положительных целых чисел
Вот простой пример использования hasNextInt() для проверки положительного int на входе.
Scanner sc = new Scanner(System.in); int number; do < System.out.println("Please enter a positive number!"); while (!sc.hasNextInt()) < System.out.println("That not a number!"); sc.next(); // this is important! >number = sc.nextInt(); > while (number
Введите положительное число!
пять
Это не число!
-3
Введите положительное число!
5
Спасибо! Получил 5Заметьте, насколько проще Scanner.hasNextInt() использовать по сравнению с более подробными try/catch Integer.parseInt / NumberFormatException комбо. По контракту a Scanner гарантирует, что если он hasNextInt() , то nextInt() мирно предоставит вам int и не будет бросать никаких NumberFormatException / InputMismatchException / NoSuchElementException .
Связанные вопросы
Пример 2: Несколько hasNextXXX на одном и том же токене
Обратите внимание, что вышеприведенный фрагмент содержит инструкцию sc.next() для продвижения Scanner до тех пор, пока не будет hasNextInt() . Важно понимать, что ни один из методов hasNextXXX не продвигает Scanner мимо любого ввода!. Вы обнаружите, что если вы опустите это line из фрагмента, затем он перейдет в бесконечный цикл на недопустимом вводе!
- Если вам нужно пропустить вход "мусор", который не прошел тест hasNextXXX , вам необходимо заранее продвинуть Scanner (например, next() , nextLine() , skip и т.д.)).
- Если один тест hasNextXXX завершился с ошибкой, вы все равно можете проверить, возможно ли это hasNextYYY !
Здесь приведен пример выполнения нескольких тестов hasNextXXX .
Scanner sc = new Scanner(System.in); while (!sc.hasNext("exit"))
5
(int) 5
ложь
(boolean) false
бла
(String) blah
1.1
(двойной) 1.1
100000000000
(длинный) 100000000000
выходОбратите внимание, что порядок испытаний имеет значение. Если a Scanner hasNextInt() , то это также hasNextLong() , но это не обязательно true наоборот. Чаще всего вы хотите сделать более конкретный тест перед более общим тестом.
Пример 3: Проверка гласных
Scanner имеет множество расширенных функций, поддерживаемых регулярными выражениями. Вот пример его использования для проверки гласных.
Scanner sc = new Scanner(System.in); System.out.println("Please enter a vowel, lowercase!"); while (!sc.hasNext("[aeiou]")) < System.out.println("That not a vowel!"); sc.next(); >String vowel = sc.next(); System.out.println("Thank you! Got " + vowel);
Введите гласный, в нижнем регистре!
5
Это не гласный!
г
Это не гласный!
е
Спасибо! Получил eВ regex, как строковый литерал Java, шаблон "[aeiou]" - это так называемый "класс символов"; он соответствует любой из букв a , e , i , o , u . Обратите внимание, что это тривиально, чтобы сделать вышеупомянутый тест нечувствительным к регистру: просто укажите такой шаблон регулярного выражения на Scanner .
Ссылки API
- hasNext(String pattern) - возвращает true , если следующий токен совпадает с шаблоном, построенным из указанной строки.
- java.util.regex.Pattern
Связанные вопросы
Ссылки
Пример 4. Использование двух Scanner сразу
Иногда вам нужно сканировать строки за строкой, с несколькими токенами на линии. Самый простой способ сделать это - использовать два Scanner , где второй Scanner принимает nextLine() из первого Scanner в качестве входного. Вот пример:
Scanner sc = new Scanner(System.in); System.out.println("Give me a bunch of numbers in a line (or 'exit')"); while (!sc.hasNext("exit")) < Scanner lineSc = new Scanner(sc.nextLine()); int sum = 0; while (lineSc.hasNextInt()) < sum += lineSc.nextInt(); >System.out.println("Sum is " + sum); >
Дайте мне кучу чисел в строке (или "exit" )
3 4 5
Сумма составляет 12
10 100 млн. ДолларовСумма составляет 110
ждать, что? Сумма 0
ВыходВ дополнение к Scanner(String) constructor, также Scanner(java.io.File) и др.
Резюме
- Scanner предоставляет богатый набор функций, таких как hasNextXXX методы для проверки.
- Правильное использование hasNextXXX/nextXXX в комбинации означает, что Scanner будет НИКОГДА не вывести InputMismatchException / NoSuchElementException .
- Всегда помните, что hasNextXXX не продвигает Scanner мимо любого ввода.
- Не стесняйтесь создавать несколько Scanner , если это необходимо. Два простых Scanner часто лучше, чем один сложный Scanner .
- Наконец, даже если у вас нет планов использовать расширенные функции регулярного выражения, имейте в виду, какие методы основаны на регулярных выражениях, а какие нет. Любой метод Scanner , который принимает аргумент String pattern , основан на регулярном выражении.
- Совет: простой способ превратить любой String в литеральный шаблон - Pattern.quote it.