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

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

Java的解决scheme是最好的。

伪代码。 使用一个数组来强制100个元素被捕获并且什么都不做的exception。

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

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

知道你的图书馆。

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

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

说明:

  • java.util.BitSet是一个方便的小类,它表示一个任意大(非稀疏)的正整数集合。 (它确实有这么糟糕的一点:不是最终的,不必要的线程安全的,不支持build设好等)。
  • 扩展BitSet允许我只写一次java.util 。 JDK7“钻石操作员”应该有助于减less与genericstypes的重复,但对于更常见的情况没有帮助。 🙁
  • 双大括号是双大括号成语 – 一个匿名的内部类只包含一个实例初始化。 这是一个黑客。 它增加了运行时间的大小,从而增加了启动时间。 如果使用pack200.gz,分发大小可以忽略不计。 我认为现代世界已经做好了准备。 你的同事可能不是。 也许开始使用它来testingda
  • BitSet.set在set中设置了一个位(这里“set”的两个完全不同的含义 – 我喜欢它)。 这是一个半开放的范围 – 独家顶级价值; 包括底部。 将1加到顶部以包含100。
  • BitSet.toString实际上是由API文档精确定义的。
  • 通过在J2SE 5.0中引入Appendable接口, append被添加到PrintStream中。 它本质上是一个子string,并打印结果。 (一个小秘密:这实际上并没有保证规范刷新输出,但实现总是会的。)
  • 从1开始追加,从长度上取1,从BitSet的string表示中BitSet大括号。
  • “了解你的图书馆” 采取从Josh Bloch。 看看Java Puzzlers,拼图94.真的很高兴知道库中的内容。 至less知道在哪里看。 节省您的时间,节省维护时间,第一时间做好准备。

在任何情况下都不要做这个事情!

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

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

我现在要去洗手。

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

我不敢相信没有人提出这个build议:

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

查看C#线程中的Divide + Conquer答案。 这是邪恶的,但辉煌的:

如何打印1到100没有任何循环使用C#

这是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(); } } 

当然有:

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

在C ++中:

 #include <iostream> class a { static unsigned i; public: a() { std::cout << ++i << std::endl; } }; unsigned a::i = 0U; int main() { a array[100]; } 

该解决scheme既不使用循环也不使用recursion来打印从1到100的数字。

从pastebin下载

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

有没有办法打印数字从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"); 

下一个问题?

或者如果你喜欢使用reflection:-)

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

是的,这是可能的,但它是可怕的。 有许多方法可以使用recursion或嵌套types创build,而stream控制则使用exception处理。 这没有现实世界的应用IMO,应该不惜代价在实际的代码。

下面是一个使用recursiontypes实例化和exception处理来控制终止的例子。 它打印的数字是降序的,但是只要从打印的值中减去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 

build立在雅可比的答案,但没有抓住。 (Upvote回答。)

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

说明:

  • Semaphore允许在阻塞之前获取指定数量的许可证。
  • 我不想两次写java.util.concurrent ,所以我伺机扩展Semaphore
  • 这使用一个匿名的内部类。 匿名并不意味着它不是一个types。 因此,我可以调用一个没有在基types/实现接口中声明的方法。
  • acquireUninterruptibly意味着我不必宣布烦人的检查exception。
  • 没有人说这个计划不得不终止。

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

没有条件(没有快捷布尔运算符,没有?操作符,没有例外),没有循环:

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

说明:

  • 定义一个类,它的toString方法在重复调用时返回连续的整数
  • 创build一个具有100个元素的向量,这是该类的实例
  • 打印vector(Vector的toString方法返回其所有元素的toString值的string)

这里是一个使用线程(我夸大了hibernate时间来解决系统速度的波动)。 我想不出一个办法摆脱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); } } 

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

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

线程安全,可configuration,没有例外,不依赖API的副作用,只是简单的面向对象和一些微不足道的math。


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

  • ( x >>> n )expression式将整数值x所有位右移n位。 低位通过这个操作简单地从右侧落下,而从左侧进入的新位总是0

  • 所以( x >>> 31 )的效果是将x的最高位移到最低位,并把x所有其他位设置为0 。 对于x所有可能的值,现在的结果总是为01

  • 由于int的最高位是符号位,对于正值为0 ,对于负值为1对于( x >>> 31 )的所有正值,expression式( x >>> 31 )计算结果为0对于x的所有负值,计算结果为1

  • 现在,如果firstlast都是正数,如果last大于first ,则( last - first - 1 )的结果将大于等于>= 0 ,如果last == first ,则结果为-1

  • 所以( ( last - first - 1 ) >>> 31 )如果last大于first ,则计算为0如果相等,则计算为1

现在这个值是0/1 ,用于在firstlast的比较中,在print( int first, int last )的两个实现之间切换。 首先recursion没有打印任何东西。 print( 1, 100 )调用print( 1, 99 )等等…直到last等于first ,这导致切换到print的其他实现,而这又不会执行任何操作。 所以现在栈再次展开,值按升序打印, vtab[ 0 ].print( 1, 100 )的调用正常结束。

这是一个有用的提示。

assert语句不是禁止if语句。

我的解决scheme没有冗长。 它不使用function应用程序以外的任何控制结构。 它也不使用库代码来帮助。 我的代码很容易扩展打印范围[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 (); } } 

编辑:由于这个问题被closures(为什么???)我会在这里发表我的第二个答案。 这是由汤姆霍金的通知启发,该程序不必终止。 此外,问题并不要求只打印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 (); } } 

另一个分而治之:

 public class Print100 { public static void main (String...args) { Runnable r1 = new Runnable () { int n; public void run () { System.out.println(++n); } }; fourTimes(fiveTimes(fiveTimes(r1))).run(); } public static Runnable twice (Runnable a) { return add(a,a); } public static Runnable fourTimes (Runnable a) { return twice(twice(a)); } public static Runnable fiveTimes (Runnable a) { return add(a,fourTimes(a)); } public static Runnable add (final Runnable a, final Runnable b) { return new Runnable () { @Override public void run () { a.run(); b.run(); } }; } } 

System.out.println(“从1到100的数字”)

实现recursion调用并打印数字。 configuration您的虚拟机在100次调用后不能运行。 没有条件,没有循环。 咳嗽 😉

滥用作为条件的例外。

 public class Main { private static int[] stopper = new int[100]; public static void main(String[] args) { try { print(1); } catch(ArrayIndexOutOfBoundsException e) { // abuse of try catch } } private static void print(int i) { System.out.println(i); stopper[i] = i; print(i + 1); } } 

没有任何循环和条件:

 public static void recfunc(int a[], int i) { System.out.println(i); int s = a[i]; recfunc(a, i + 1); } public static void main(String[] args) { int[] a = new int[100]; try { recfunc(a, 1); } catch (Exception e) { } } 

recursion和没有,如果我认为使用“?” 适用于:

 public static int recfunc(int i) { System.out.println(i); return (i < 100) ? recfunc(i + 1) : 0; } public static void main(String[] args) { recfunc(1); } 

如果尝试和抓住是合法的,我会认为这将是简单和相当干净的recursion,然后除以零,当你完成。 除了所有这一切,当你为了乐趣和利润而被分为零时,它总是很摇滚。

 public class Main { public static void main(String[] args) { count(100); } private static int count(int x) { try { int value=1/x; count(x-1); System.out.println(x); } catch (Exception e){ return 0; } return 1; } 

我是一个.Net开发人员,但我猜想有一个相当于Java的Java …

 static int i = 1; static System.Timers.Timer timer = new System.Timers.Timer(); static void Main(string[] args) { timer.Interval = 10; //milliseconds timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Enabled = true; timer.Start(); //let the timer complete... (3000 to show the output stops) System.Threading.Thread.CurrentThread.Join(3000); } static void timer_Elapsed(object sender, ElapsedEventArgs e) { Console.WriteLine(i++); timer.Enabled = (i < 101); } 

在这里没有看到这个,使用&&操作符的终止顺序。

 public class count100 { public static boolean loop(int i) { System.out.println(100-i); return i > 0 && loop(i-1); } public static void main(String[] args) { loop(99); } } 

这让我想起了几年前和几年前对TI-55的编程。 它有32个可编程的指令步骤,以及一个可以跳转到指令零的RESET指令,所以可以实现简单的循环。 问题是让它停下来,这个问题变成了一个导致错误的操作,例如被零除。

从而:

 public static void main(String[] args) { printN(100); } private static void printN(int n) { try { int t = 1/n; // Exception when n is 0 printN(n-1); // Recurse, down to 0 System.out.println(n); } catch (Exception ex) { // Stop recursing } } 

注意:是的,我知道这与@ Yacoby的解决scheme类似。

这个答案是不正确的,甚至不会看起来会运行。 ;)

它会在输出结尾得到额外的文本,但是避免循环,条件,main()和println()。 ;)

 public class OneHundred { private static int i = 1; static { OneHundred[] hundreds = new OneHundred[100]; Arrays.fill(hundreds, new OneHundred();); Thread.currentThread().setName(Arrays.toString(hundreds).replaceAll("[\\]\\[, ]+", "\n")); clear("Exception in thread \""); clear("\" "); } private static void clear(String string) { try { Field f = String.class.getDeclaredField("count"); f.setAccessible(true); f.set(string, 0); } catch (Exception ignored) { } } public String toString() { return "" + i++; } } 
 public class PrintUptoHundredWithoutIf { public static void main(String[] args) { Thread t = new Thread(task()); t.setDaemon(true); t.start(); sleep((NUMBERS_TO_PRINT * SLEEP_PERIOD_IN_MILLIS) + OS_SLEEP_RESPONSE_IN_MILLIS); } private static final int SLEEP_PERIOD_IN_MILLIS = 1000; private static final int NUMBERS_TO_PRINT = 100; private static final int OS_SLEEP_RESPONSE_IN_MILLIS = 110; public void printUptoHundred(byte seq) { int posVal = Math.abs(~seq); System.out.println(posVal); sleep(SLEEP_PERIOD_IN_MILLIS); printUptoHundred((byte) posVal); } private static Runnable task() { return new Runnable() { @Override public void run() { new PrintUptoHundredWithoutIf().printUptoHundred((byte) 0); } }; } private static void sleep(int millis) { try { Thread.sleep(millis); } catch (Exception e) { e.printStackTrace(); } } } 

它是否必须是Java? 如果允许ruby:

 puts [*1..100].join("\n") 

我想在Java中看到这个简洁的东西。