Как в Java напечатать числа от 1 до 100 без циклов и условий?

Статья из группы Java Developer
участников
Этот пост предназначен в первую очередь для тех, кто готовится к собеседованиям. Именно там любят задавать подобного рода головоломки. На самом деле поставленную задачу легче и логичнее решать именно с циклами и условиями. И, думаем, любой студент JavaRush сможет это сделать после четвертого уровня квеста Java Syntax. Но подавляющее большинство приведённых способов рассчитаны на тех, кто уже «зашёл» в Java Multithreading. Примечание: речь идёт о том, чтобы не использовать циклы и условия непосредственно. На самом деле они неявно "вшиты" в большинство указанных решений. Как в Java напечатать числа от 1 до 100 без циклов и условий?  - 1
Возможно, у вас есть своё решение для этой задачки? Делитесь в комментариях!

Итак, способ 1: просто напиши это!

Разумеется, первое, что приходит в голову новичку — прямой перебор. Нерационально, но просто и понятно. Точно так, как мы решали задачи на первых уровнях JavaRush.
System.out.println("1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100");
Но, согласитесь, это как-то скучно. Поэтому можно воспользоваться вторым способом.

Способ 2: используй строки и переопределение toString

public static void main(String[] args) {

        Object[] numbers = new Object[100];
        Arrays.fill(numbers, new Object() {    //создаем анонимный класс
            private int count = 0;
            @Override
            public String toString() {
                return Integer.toString(++count);
            }
        });
        System.out.println(Arrays.toString(numbers));

    }
Аннотация @Override указывает, что мы собираемся переопределить метод базового класса. В данном случае мы переопределяем toString. На самом деле это, как и почти все следующие варианты решения содержат циклы. Просто эти циклы вшиты в используемые методы.

Способ 3: используй рекурсию

Чтобы понять рекурсию, нужно понять рекурсию. Рекурсия или вызов функцией самой себя — тема очень интересная, и не всегда понятная сразу. На JavaRush её проходят в квесте Java Collections (для полноты картинки), но на самом деле её можно понять и использовать (или не использовать… почему — узнаете во время изучения темы!) гораздо раньше, сразу после изучения циклов и условных переходов.
public class Recursion {

    public void ShowNums(int i) {
    // метод, который печатает

        int x = 1;

// блок try проверяет, достигли ли мы нуля
        try {
            int m = x / i;				// здесь выбрасывается исключение при i = 0
            System.out.println(i);
            i--;
            ShowNums(i);				// а вот и рекурсивный вызов
        }
        catch(ArithmeticException e) {
		// деление на нуль выбрасывает ArithmeticException
            return;					// Останавливается при попытке деления на нуль
        }

    }

     public static void main(String[] args) {

        Recursion r = new Recursion();
        r.ShowNums(100);				// вызов метода со значением 100
    }

}
Обратите внимание: здесь вывод производится не в прямом, а в обратном порядке. Попробуйте изменить код, чтобы числа выводились так, как сказано в условии, то есть от 1 до 100. Ждём решений в комментариях!

Способ 4: используй семафоры

public class To100 {
    public static void main(String[] args) {
        final int max = 100;
        new java.util.concurrent.Semaphore(max) {
            void go() {
                acquireUninterruptibly();
                System.err.println(max-availablePermits());
                go();
            }
        }.go();
    }
}
Семафоры — это средство синхронизации для доступа к ресурсу. В Java семафоры представлены классом Semaphoreбиблиотеки java.util.concurrent.

Способ 5: используй нити

public class Counter extends Thread{

    private int cnt;

    public Counter(){
        this.cnt = 0;
    }

    private void increment(){
        System.out.println(cnt++);
        try{
            Thread.sleep(1000);
        }catch(Exception e){}
        increment();
    }

    public void run(){
        increment();
    }

    public static void main(String[] args) throws Exception{
        Counter cntr = new Counter();
        cntr.start();
        cntr.join(100000);
        cntr.interrupt();
        System.exit(0);
    }
}

Способ 6: знай свои библиотеки!

В Java есть много всего интересного. Например, класс java.util.BitSet. Он позволяет создать битовый вектор, размер которого изменяется динамически. То есть объект класса BitSet — некий упорядоченный набор битов со значениями true или false. Изначально все биты равны false. Для хранения набора выделяется объем памяти, необходимый для хранения вектора вплоть до старшего бита, который устанавливался или сбрасывался в программе — все превышающие его биты считаются равными false.
public class To100 {
    public static void main(String[] args) {
        String set = new java.util.BitSet() {{ set(1, 100+1); }}.toString();
        System.out.append(set, 1, set.length()-1);
    }
}

Способ 7: используй класс Vector

Да, класс вектор — устаревший, и используется крайне редко. Тем не менее, почему бы и нет?
import java.util.Vector;

public class PrintOneToHundered {
  static int i;
  PrintOneToHundered() {}
  public String toString() { return ++i+""; }
  public static void main(String[] args) {
    Vector v1  =new Vector(); v1  .add(new PrintOneToHundered());
    Vector v2  =new Vector(); v2  .addAll(v1 ); v2  .addAll(v1 );
    Vector v4  =new Vector(); v4  .addAll(v2 ); v4  .addAll(v2 );
    Vector v8  =new Vector(); v8  .addAll(v4 ); v8  .addAll(v4 );
    Vector v16 =new Vector(); v16 .addAll(v8 ); v16 .addAll(v8 );
    Vector v32 =new Vector(); v32 .addAll(v16); v32 .addAll(v16);
    Vector v64 =new Vector(); v64 .addAll(v32); v64 .addAll(v32);
    Vector v100=new Vector(); v100.addAll(v64); v100.addAll(v32); v100.addAll(v4);
    System.out.println(v100);
  }
}
По материалам Quora
Комментарии (19)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Tehron Ahatov
Уровень 17, Душанбе , Таджикистан
6 сентября 2021, 15:32
package com.tehron;

public class Main {

    public static void main(String[] args) {

        Recursion r = new Recursion();
        r.ShowNums(100);

    }
}


class Recursion {

    private int y = 1;

    public void ShowNums(int i) {
        // метод, который печатает

        int x = 1;

// блок try проверяет, достигли ли мы нуля
        try {
            int m = x / i;				// здесь выбрасывается исключение при i = 0
            System.out.println(y);
            y++;
            i--;
            ShowNums(i);				// а вот и рекурсивный вызов
        }
        catch(ArithmeticException e) {
            // деление на нуль выбрасывает ArithmeticException
            return;					// Останавливается при попытке деления на нуль
        }

    }
}
Evgeny Strokov Enterprise Java Developer в СберТех
12 марта 2021, 17:57
Stream.iterate(1, x -> ++x).limit(100).forEach(x -> System.out.print(x + " "));
Лейтенант Ден
Уровень 31, Москва, Россия
16 августа 2020, 11:47
от 1 до 100 с помощью рекурсии.
public class Recursion {

    public void ShowNums(int i) {
        // метод, который печатает

// блок try проверяет, достигли ли мы нуля
        try {
            int x = 101 - i;
            int m = x / i;				// здесь выбрасывается исключение при i = 0
            System.out.println(x);
            i--;
            ShowNums(i);				// а вот и рекурсивный вызов
        }
        catch(ArithmeticException e) {
            // деление на нуль выбрасывает ArithmeticException
            return;					// Останавливается при попытке деления на нуль
        }


    }

    public static void main(String[] args) {

        Recursion rec = new Recursion();
        rec.ShowNums(100);
    }
}
John Smith
Уровень 31, Киев, Украина
4 октября 2019, 13:33
System.out.println(Arrays.toString(IntStream.range(1, 101).toArray()));
yadiver
Уровень 6
21 июля, 18:59
куда уж лаконичнее )
Marat
Уровень 16, Одесса, Украина
25 мая 2019, 22:37
public static String showNums(int first, int last){

    if(first==last)
      return ""+last;
    else
      return (first+showNums(first+1,last));

  }
8 апреля 2019, 08:48
import java.util.Scanner;

public class Printer {

    private int cnt = 1;

    private interface Printable {
        void print(int n);
    }

    private Printable[] printers = new Printable[]
            {
                    (n) -> {},
                    new Printable() {
                        public void print(int n) {
                            System.out.println(cnt++);
                            printers[1 % n].print(n - 1);
                        }
                    }
            };

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Enter Number:  ");
        int n = in.nextInt();
        Printer printer = new Printer();
        printer.printers[1].print(n);
    }
}
Александр
Уровень 23, Россия
4 апреля 2019, 09:35
System.out.println(-(i-101));
Максим Тымковский
Уровень 34, Санкт-Петербург, Россия
7 марта 2019, 21:30
public class Recursion { public void ShowNums(int i, int x) { if (i == 1) System.out.println(x); else { System.out.println(x); x++; ShowNums(i - 1, x); } } public static void main(String[] args) { Recursion r = new Recursion(); r.ShowNums(100, 1); // вызов метода со значением 100 } }
Anastasiia
Уровень 20, США
Expert
5 января 2018, 02:06
Потрясающе!
Максим
Уровень 40, Беларусь
Expert
2 января 2018, 22:57
"Обратите внимание: здесь вывод производится не в прямом, а в обратном порядке. Попробуйте изменить код, чтобы числа выводились так, как сказано в условии, то есть от 1 до 100. Ждём решений в комментариях!" Первое, что пришло на ум)) Как говорится, решение в лоб)
public class Recursion {

    public void ShowNums(int i) {
    // метод, который печатает

        int x = 1;

// блок try проверяет, достигли ли мы нуля
        try {
            int m = x / (i-101);				// здесь выбрасывается исключение при i = 0
            System.out.println(i);
            i++;
            ShowNums(i);				// а вот и рекурсивный вызов
        }
        catch(ArithmeticException e) {
		// деление на нуль выбрасывает ArithmeticException
            return;					// Останавливается при попытке деления на нуль
        }

    }

     public static void main(String[] args) {

        Recursion r = new Recursion();
        r.ShowNums(1);				// вызов метода со значением 100
    }

}
Oleg Serebrennikov
Уровень 13, Санкт-Петербург, Россия
17 апреля 2018, 10:52
Мой вариант. Но можно ли обойтись без "return i + 2"? public class Recursion { public int ShowNums(int i) { // метод, который печатает int x = 1; // блок try проверяет, достигли ли мы нуля try { int m = x / i; // здесь выбрасывается исключение при i = 0 //System.out.print(i + " "); i--; System.out.print(ShowNums(i) + " "); // а вот и рекурсивный вызов } catch(ArithmeticException e) { // деление на нуль выбрасывает ArithmeticException return i + 1; // Останавливается при попытке деления на нуль } return i + 2; } public static void main(String[] args) { Recursion r = new Recursion (); r.ShowNums(100); // вызов метода со значением 100 } }
Максим
Уровень 40, Беларусь
Expert
17 апреля 2018, 14:46
Можно. В твоем способе решения, например, так =)
public int ShowNums(int i) {
        // метод, который печатает

        int x = 1;

// блок try проверяет, достигли ли мы нуля
        try {
            int m = x / i;          // здесь выбрасывается исключение при i = 0
            //System.out.print(i + " ");
            i--;
            System.out.print(ShowNums(i) + 1 + " "); // а вот и рекурсивный вызов
        } catch (ArithmeticException e) {
            // деление на нуль выбрасывает ArithmeticException
            return i;            // Останавливается при попытке деления на нуль
        }
        return i + 1;
    }
А вообще есть еще проще и пожалуй правильнее решение. Мое предыдущее решение было неверным, так как работало только для числа 100 и никаких других. Просто оно было написано сразу, быстро, не подумав) Я уж и забыл про эту статью, но твой коммент "заставил" меня вернуться и подумать над более верным решением с минимальными изменениями (и метод остался void). Теперь на вход подается любое число и выводится набор числе от 1 до заданного числа в возрастающем порядке
public class Recursion {

    public void ShowNums(int i) {
        // метод, который печатает

        int x = 1;

// блок try проверяет, достигли ли мы нуля
        try {
            int m = x / i;             // здесь выбрасывается исключение при i = 0
            ShowNums(i - 1);      // а вот и рекурсивный вызов
            System.out.println(i);
        } catch (ArithmeticException e) {
            // деление на нуль выбрасывает ArithmeticException
            return;               // Останавливается при попытке деления на нуль
        }

    }

    public static void main(String[] args) {

        Recursion r = new Recursion();
        r.ShowNums(100);                // вызов метода со значением 100
    }

}