显示从1到100的数字,没有循环或条件

Thu*_*shy 33 java loops

有没有办法从1到100打印数字而不使用任何循环或条件,如"如果"?我们可以很容易地使用递归但是又有一个if条件.有没有办法不使用"if"?也没有重复的打印语句,或包含1到100之间所有数字的单个打印语句.

Java中的解决方案更可取.

Tom*_*ine 177

了解你的图书馆.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

(您可以使用String.replaceAll更改分隔符.例如,.replaceAll(", ", " ")用于空间分隔.)

说明:

  • java.util.BitSet是一个方便的小类,代表一组任意大(非稀疏)的正整数.(它确实有如此糟糕的位:不是最终的,不必要的线程安全,不支持构建良好等)ta.
  • Extends BitSet允许我java.util只写一次.JDK7"钻石运算符"应该有助于减少与泛型类型的重复,但对于更常见的情况没有帮助.:(
  • 双括号是Double Brace习语 - 一个只包含实例初始化的匿名内部类.这是一个黑客.它增加了运行时间大小,从而增加了启动时间.如果使用pack200.gz,分发大小可以忽略不计.我认为现代世界已经做好了准备.你的同事可能不是.也许首先将它用于测试da
  • BitSet.set在集合中设置了一点(两个完全不同的含义"set"在那里 - 我喜欢它).这是一个半开放的范围 - 最高价值的独家; 底部包容.在顶部添加1以包括100.
  • BitSet.toString 实际上是由API文档精确定义的.
  • append加入到PrintStream与引入的Appendable在J2SE 5.0界面.它本质上是一个子串并打印结果.(一个小秘密:实际上并没有通过规范来保证刷新输出,但实现总是如此.)
  • 从1开始追加,并从长度中取出一个从字符串表示中删除大括号BitSet.
  • "了解你的图书馆." 取自Josh Bloch.请参阅Java Puzzlers,谜题94.了解库中的内容真的很好.至少知道在哪里看.节省您的时间,节省维护时间,并在第一时间做到正确.

  • 这是一个聪明的解决方案,虽然我说使用一个使用循环和/或条件来完成工作的库可能不符合问题的精神 (19认同)
  • 我想再多投票几次,因为除了truppo的荒谬回答之外,它是唯一一个不使用控制结构的人.是的,try/catch是一个控制结构. (5认同)

z *_* - 119

在任何SANE情况下都不要这样做!

public class Fail {

    public void thisFails(int x){
        System.out.println(x);
        Integer[] bigArray = new Integer[9450];
        thisFails(x+1);
    }

    public static void main(String[] args) {
        Fail failure = new Fail();
        failure.thisFails(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

当使用1m的堆空间(java -Xmx1m Fail)运行它时,它将在第100次递归时用完堆.

...

我现在要去洗手了.

  • @silky,你的声誉足够高,你应该知道循环和递归调用是可以用来实现相同结果的不同东西.我们也可以仅使用通用逻辑门(NAND/NOR)来实现相同的结果,但这并不意味着一堆NOR门是一个环路. (11认同)
  • 哇,恭喜你弄清楚这需要多少堆空间. (4认同)
  • @silky:我看不到循环,这是一个递归调用.这是一个令人敬畏的IMO方式 (2认同)
  • @silky重新阅读了这个问题,他说递归被允许但由于停止条件需要if而无法使用; 除了 - 循环和递归不是一回事,它们可以用不同的方式实现相同的东西 (2认同)

Nik*_*iki 70

有没有办法从1到100打印数字而不使用任何循环或条件,如"如果"?

我不敢相信没有人建议这个:

System.out.println("numbers from 1 to 100 without using any loops or conditions like \"if\"?");
Run Code Online (Sandbox Code Playgroud)


Ada*_*ope 64

查看C#主题中的Divide + Conquer答案.这是邪恶的,但很棒:

如何使用C#打印1到100而不进行任何循环

这是Java版本:

public class Application {

    public static void main(String[] args) {
        Print64Numbers();
        Print32Numbers();
        Print4Numbers();
    }

    private static int currentNumber = 0;

    private static void Print1Number() { System.out.println(++currentNumber); }
    private static void Print2Numbers() { Print1Number(); Print1Number(); }
    private static void Print4Numbers() { Print2Numbers(); Print2Numbers(); }
    private static void Print8Numbers() { Print4Numbers(); Print4Numbers(); }
    private static void Print16Numbers() { Print8Numbers(); Print8Numbers(); }
    private static void Print32Numbers() { Print16Numbers(); Print16Numbers(); }
    private static void Print64Numbers() { Print32Numbers(); Print32Numbers(); }
}
Run Code Online (Sandbox Code Playgroud)


Yac*_*oby 48

伪代码.使用数组在100个元素之后强制执行异常,这些元素被捕获并且什么都不做.

function r(array a, int index){
    a[index] = a[index-1]+1
    print a[index]
    r(a, index+1)
}

try{
    array a;
    a.resize(101)
    r(a, 1)
}catch(OutOfBoundsException){
}
Run Code Online (Sandbox Code Playgroud)

编辑
Java代码:

public void printTo100(){
    int[] array = new int[101];
    try{
        printToArrayLimit(array, 1);
    }catch(ArrayIndexOutOfBoundsException e){
    }
}
public void printToArrayLimit(int[] array, int index){
    array[index] = array[index-1]+1;
    System.out.println(array[index]);
    printToArrayLimit(array, index+1);
}
Run Code Online (Sandbox Code Playgroud)

  • @Jorn不是不是.他们是两个不同的东西. (9认同)
  • 递归循环仍然是循环... (7认同)
  • try/catch计数是否为条件语句?这就像说"如果有例外......" (7认同)
  • a.fill(101)是不必要的,只需设置[index] = 0并打印索引.当然,这仍然在JVM内部使用'if'语句... (2认同)

tru*_*ppo 41

当然有:

System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
System.out.println(6);
System.out.println(7);
System.out.println(8);
System.out.println(9);
System.out.println(10);
System.out.println(11);
System.out.println(12);
System.out.println(13);
System.out.println(14);
System.out.println(15);
System.out.println(16);
System.out.println(17);
System.out.println(18);
System.out.println(19);
System.out.println(20);
System.out.println(21);
System.out.println(22);
System.out.println(23);
System.out.println(24);
System.out.println(25);
System.out.println(26);
System.out.println(27);
System.out.println(28);
System.out.println(29);
System.out.println(30);
System.out.println(31);
System.out.println(32);
System.out.println(33);
System.out.println(34);
System.out.println(35);
System.out.println(36);
System.out.println(37);
System.out.println(38);
System.out.println(39);
System.out.println(40);
System.out.println(41);
System.out.println(42);
System.out.println(43);
System.out.println(44);
System.out.println(45);
System.out.println(46);
System.out.println(47);
System.out.println(48);
System.out.println(49);
System.out.println(50);
System.out.println(51);
System.out.println(52);
System.out.println(53);
System.out.println(54);
System.out.println(55);
System.out.println(56);
System.out.println(57);
System.out.println(58);
System.out.println(59);
System.out.println(60);
System.out.println(61);
System.out.println(62);
System.out.println(63);
System.out.println(64);
System.out.println(65);
System.out.println(66);
System.out.println(67);
System.out.println(68);
System.out.println(69);
System.out.println(70);
System.out.println(71);
System.out.println(72);
System.out.println(73);
System.out.println(74);
System.out.println(75);
System.out.println(76);
System.out.println(77);
System.out.println(78);
System.out.println(79);
System.out.println(80);
System.out.println(81);
System.out.println(82);
System.out.println(83);
System.out.println(84);
System.out.println(85);
System.out.println(86);
System.out.println(87);
System.out.println(88);
System.out.println(89);
System.out.println(90);
System.out.println(91);
System.out.println(92);
System.out.println(93);
System.out.println(94);
System.out.println(95);
System.out.println(96);
System.out.println(97);
System.out.println(98);
System.out.println(99);
System.out.println(100);
Run Code Online (Sandbox Code Playgroud)

  • 这是非常难过的,我甚至不明白这是如何得到这么多的选票.这是Stackoverflow imho的典型问题.微不足道的问题的琐碎答案导致很多人投票,同时花10分钟或更长时间提供详细的答案和深刻的解释,并提到一个棘手的问题将没有给你带来任何东西(除了帮助的满意:) :)因为许多人甚至不会得到它! (128认同)
  • @Gregory我认为这得到了大多数选票,因为这对于一个愚蠢无用的问题来说是一个直截了当但无用的答案. (68认同)
  • 我不明白为什么关于这个答案的投诉得到了这么多的赞成!对于提出的问题,这是最简单的正确答案! (26认同)
  • 这是唯一正确的答案; 每隔一个人就会使用某种循环(直接或间接). (13认同)
  • 这不起作用.好吧,它打印的数字从1到5,但三个点是什么? (3认同)
  • 这是一个非常有效的答案.基本上它是预先计算答案然后输出它.预计算结果是一种非常有效的编程技术. (2认同)
  • 我认为循环用于创建此代码行... (2认同)

mis*_*tor 36

在C++中:

#include <iostream>

class a {
  static unsigned i;

public:
  a() {
    std::cout << ++i << std::endl;
  }
};

unsigned a::i = 0U;

int main() {
  a array[100];
}
Run Code Online (Sandbox Code Playgroud)

此解决方案既不使用循环也不使用递归来打印1到100之间的数字.


Jim*_*mmy 22

pastebin下载

System.out.println((new URL("http://pastebin.com/pastebin.php?dl=f722c7eb0")).getContent())
Run Code Online (Sandbox Code Playgroud)


Osc*_*Ryz 16

有没有办法从1到100打印数字而不使用任何循环或条件,如"如果"?

使用的优化版本, :

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"); 
Run Code Online (Sandbox Code Playgroud)

下一个问题?


Mik*_*ike 15

或者如果你想使用反射:-)

public class Print100 {

    public static void emit0(int index) throws Exception {
        System.out.println(index);

        String next = new StringBuilder()
                          .append("emit")
                          .append(index / 100)
                          .toString();

        Print100.class.getMethod(next, Integer.TYPE)
                          .invoke(null, index+1);
    }

    public static void emit1(int index) {

    }

    public static void main(String[] args) throws Exception {
        emit0(1);
    }

}
Run Code Online (Sandbox Code Playgroud)


LBu*_*kin 12

是的,这是可能的,但它很可怕.有许多方法可以使用递归或嵌套类型创建,以及流控制的异常处理.这没有真实的应用程序IMO,应该不惜一切代价在实际代码中避免.

这是一个使用递归类型实例化和异常处理来控制终止的示例.它打印的数字是降序,但是通过从打印的值中减去99(或任何常数)来改变升序将是微不足道的.

class PrintVal
{
  // called with a list containing as many items as you want, less one...
  public PrintVal( List<int> items )
  {
      System.out.println(items.size()+1);  // print the size of the list
      try { 
        items.remove( items.size()-1 );  // will throw when items is empty
        new PrintVal( items );
      }
      catch( Exception ) { /* swallow and terminate */ }
  }
}

// setup and invocation that performs the output
ArrayList<int> strList = new ArrayList<int>( new int[99] );
PrintVal instance = new PrintVal( strList );  // all output happens here
Run Code Online (Sandbox Code Playgroud)


Tom*_*ine 12

以Yacoby的答案为基础,但没有抓住.(请回答.)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

说明:

  • Semaphore 允许在阻止之前获取指定数量的许可.
  • 我不想写java.util.concurrent两次,所以我机会性地扩展了Semaphore.
  • 这使用匿名内部类.匿名并不意味着它不是一种类型.因此,我可以调用一个未在基类型/实现的接口中声明的方法.
  • acquireUninterruptibly 意味着我不必声明烦人的检查异常.
  • 没有人说该计划必须终止.


use*_*421 10

让Arrays完成这项工作:

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));
}
Run Code Online (Sandbox Code Playgroud)


Cur*_*urd 9

没有条件(没有捷径布尔运算符,没有? - 运算符,没有异常),没有循环:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

说明:

  • 定义一个类,其toString方法在重复调用时返回连续的int
  • 创建一个包含100个元素的向量,这些元素是类的实例
  • 打印向量(Vector的toString-method返回其所有元素的toString值的字符串)


jck*_*111 7

这是使用线程的一个(我夸大了睡眠时间以考虑系统速度的波动).我想不出摆脱try/catch的方法:

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

}
Run Code Online (Sandbox Code Playgroud)


x4u*_*x4u 6

好吧,我迟到了,答案已经被接受,但我想知道为什么没有人使用干净简单的计数器呢?

public class Counter
{
    static Counter[] vtab = new Counter[]
    {
        new Counter(),
        new Counter() { public void print( int first, int last ) {} }
    };

    public void print( int first, int last )
    {
        vtab[ ( last - first - 1 ) >>> 31 ].print( first, last - 1 );
        System.out.println( last );
    }

    public static void main( String[] args )
    {
        vtab[ 0 ].print( 1, 100 );
    }
}
Run Code Online (Sandbox Code Playgroud)

线程安全,可配置,没有异常,不依赖于API副作用,只是简单的OOP和一些简单的数学.


对于那些不熟悉二元运算符的人来说,它是如何工作的:

  • ( x >>> n )表达式移动整数值的所有位x由向右n的地方.低位通过此操作简单地从右侧掉落,并且从左侧进入的新位始终是0.

  • 因此,效果( x >>> 31 )是将最高位移动x到最低位并将所有其他位设置x0.现在结果总是0或者1是所有可能的值x.

  • 作为的最高位int是符号位,其是0为正值和1负值,则表达式( x >>> 31 )的计算结果为0对于所有positve值x,并1为所有负值x.

  • 现在,如果这两个firstlast是正数,如果last大于first,结果( last - first - 1 )将是>= 0,如果last == first这将是-1.

  • 因此,( ( last - first - 1 ) >>> 31 )评估0if last是否大于first并且变为1是否相等.

现在,这个值0/1被用于的2个实施方式之间切换print( int first, int last )基于所述比较firstlast.首先,递归发生而不打印任何东西.print( 1, 100 )调用print( 1, 99 )等等......直到last等于first导致切换到另一个实现的等于哪个print实际上什么也没做.所以现在堆栈再次展开,值按升序打印,并且vtab[ 0 ].print( 1, 100 )正常调用完成.


S.L*_*ott 5

这是一个有用的提示.

assert声明不是禁止的if声明.


Tho*_*ing 5

我的解决方案没有冗长.它不使用除功能应用程序之外的任何控制结构.它也不使用库代码来帮助.我的代码很容易扩展,可以打印出范围[a,b].只要改变conts [n / 100]conts [(n - a) / (b - a)]线路改变和new Printable (1)new Printable (a).

To100.java:

class Printable {
  private static final Continuation[] conts = {new Next (), new Stop ()};

  private final int n;
  private final Continuation cont;

  Printable (int n) {
    this.n = n;
    this.cont = conts [n / 100];
  }

  public void print () {
    System.out.println (n);
    cont.call (n);
  }
}

interface Continuation {
  public void call (int n);
}

class Next implements Continuation {
  public void call (int n) {
    new Printable (n + 1).print ();
  }
}

class Stop implements Continuation {
  public void call (int n) {
    // intentionally empty
  }
}

class To100 {
  public static void main (String[] args) {
    new Printable (1).print ();
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:由于这个问题已经关闭(为什么???)我会在这里发布我的第二个答案.它的灵感来自Tom Hawtin的通知,该程序不必终止.此问题也不要求只打印数字1-100(甚至按顺序).

To100Again.java:

class To100Again extends Thread {
  private static byte n;
  public void run () {
    System.out.println (n++);
    new To100Again ().start ();
    System.gc();
  }
  public static void main (String[] args) {
    new To100Again ().start ();
  }
}
Run Code Online (Sandbox Code Playgroud)