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

我试图使用C#从1到100打印数字而不使用循环。 有什么线索吗?

可能是递归?

public static void PrintNext(i) { if (i <= 100) { Console.Write(i + " "); PrintNext(i + 1); } } public static void Main() { PrintNext(1); } 

没有循环,没有条件,也没有硬编码的文字输出,又称“分而治之FTW”解决方案:

 class P { static int n; static void P1() { System.Console.WriteLine(++n); } static void P2() { P1(); P1(); } static void P4() { P2(); P2(); } static void P8() { P4(); P4(); } static void P16() { P8(); P8(); } static void P32() { P16(); P16(); } static void P64() { P32(); P32(); } static void Main() { P64(); P32(); P4(); } } 

替代方法:

 using System; class C { static int n; static void P() { Console.WriteLine(++n); } static void X2(Action a) { a(); a(); } static void X5(Action a) { X2(a); X2(a); a(); } static void Main() { X2(() => X5(() => X2(() => X5(P)))); } } 
 Console.Out.WriteLine('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'); 

多一个:

 Console.WriteLine( String.Join( ", ", Array.ConvertAll( Enumerable.Range(1, 100).ToArray(), i => i.ToString() ) ) ); 
 using static IronRuby.Ruby; class Print1To100WithoutLoopsDemo { static void Main() => CreateEngine().Execute("(1..100).each {|i| System::Console.write_line i }"); } 

嘿,为什么不呢?

 Console.WriteLine('1'); Console.WriteLine('2'); ... Console.WriteLine('100'); 

…或者你会接受递归解决方案吗?

编辑:或者您可以这样做并使用变量:

 int x = 1; Console.WriteLine(x); x+=1; Console.WriteLine('2'); x+=1; ... x+=1 Console.WriteLine('100'); 
 Enumerable.Range(1, 100) .Select(i => i.ToString()) .ToList() .ForEach(s => Console.WriteLine(s)); 

不确定这是否算作循环是隐藏的,但如果它是合法的,它是问题的惯用解决方案。 否则你可以这样做。

  int count = 1; top: if (count > 100) { goto bottom; } Console.WriteLine(count++); goto top; bottom: 

当然,这实际上是一个循环将被转换为无论如何,但是这些天来编写这样的代码肯定不赞成。

 Enumerable.Range(1, 100).ToList().ForEach(i => Console.WriteLine(i)); 

以下是上述代码中发生的情况的细分:

  • Enumerable.Range返回指定范围的整数作为IEnumerator
  • Enumerable.ToList 将IEnumerable 转换为List
  • List .ForEach采用lamdba函数并为列表中的每个项调用它

绩效考虑

ToList调用将导致为所有项目分配内存(在上面的示例中为100个int)。 这意味着O(N)空间复杂性。 如果这是您的应用程序中的一个问题,即如果整数范围可能非常高,那么您应该避免ToList并直接枚举项目。

不幸的是,ForEach不是开箱即用的IEnumerable扩展的一部分(因此需要在上面的例子中转换为List)。 幸运的是,这很容易创建:

 static class EnumerableExtensions { public static void ForEach(this IEnumerable items, Action func) { foreach (T item in items) { func(item); } } } 

使用上面的IEnumerable扩展,现在在需要将操作应用于IEnumerable的所有地方,您只需使用lambda调用ForEach即可。 所以现在原始示例如下所示:

 Enumerable.Range(1, 100).ForEach(i => Console.WriteLine(i)); 

唯一的区别是我们不再调用ToList,这会导致常量(O(1))空间使用…如果您处理的是大量项目,这将是一个非常显着的增益。

没有循环,没有递归,只是一个类似哈希表的函数数组来选择如何分支:

 using System; using System.Collections.Generic; namespace Juliet { class PrintStateMachine { int state; int max; Action[] actions; public PrintStateMachine(int max) { this.state = 0; this.max = max; this.actions = new Action[] { IncrPrint, Stop }; } void IncrPrint(Action next) { Console.WriteLine(++state); next(); } void Stop(Action next) { } public void Start() { Action action = actions[Math.Sign(state - max) + 1]; action(Start); } } class Program { static void Main(string[] args) { PrintStateMachine printer = new PrintStateMachine(100); printer.Start(); Console.ReadLine(); } } } 

只是为了丑陋的字面解释:

 Console.WriteLine("numbers from 1 to 100 without using loops, "); 

(你现在或以后可以笑,还是不笑)

当我回答这个问题时,有人已经拥有了它,所以无论如何,这是对Caleb的信任:

 void Main() { print(0, 100); } public void print(int x, int limit) { Console.WriteLine(++x); if(x != limit) print(x, limit); } 

我可以想到两种方式。 其中一个涉及大约100行代码!

还有另一种方法可以多次重用一些代码而不使用while / for循环…

提示:创建一个打印从1到N的数字的函数。应该很容易使其适用于N = 1.然后考虑如何使其适用于N = 2。

使用正则表达式

 using System.Text.RegularExpressions; public class Hello1 { public static void Main() { // Count to 128 in unary string numbers = "x\n"; numbers += Regex.Replace(numbers, "x+\n", "x$&"); numbers += Regex.Replace(numbers, "x+\n", "xx$&"); numbers += Regex.Replace(numbers, "x+\n", "xxxx$&"); numbers += Regex.Replace(numbers, "x+\n", "xxxxxxxx$&"); numbers += Regex.Replace(numbers, "x+\n", "xxxxxxxxxxxxxxxx$&"); numbers += Regex.Replace(numbers, "x+\n", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$&"); numbers += Regex.Replace(numbers, "x+\n", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$&"); // Out of 1..128, select 1..100 numbers = Regex.Match(numbers, "(.*\n){100}").Value; // Convert from unary to decimal numbers = Regex.Replace(numbers, "x{10}", "<10>"); numbers = Regex.Replace(numbers, "x{9}", "<9>"); numbers = Regex.Replace(numbers, "x{8}", "<8>"); numbers = Regex.Replace(numbers, "x{7}", "<7>"); numbers = Regex.Replace(numbers, "x{6}", "<6>"); numbers = Regex.Replace(numbers, "x{5}", "<5>"); numbers = Regex.Replace(numbers, "x{4}", "<4>"); numbers = Regex.Replace(numbers, "x{3}", "<3>"); numbers = Regex.Replace(numbers, "x{2}", "<2>"); numbers = Regex.Replace(numbers, "x{1}", "<1>"); numbers = Regex.Replace(numbers, "(<10>){10}", "<100>"); numbers = Regex.Replace(numbers, "(<10>){9}", "<90>"); numbers = Regex.Replace(numbers, "(<10>){8}", "<80>"); numbers = Regex.Replace(numbers, "(<10>){7}", "<70>"); numbers = Regex.Replace(numbers, "(<10>){6}", "<60>"); numbers = Regex.Replace(numbers, "(<10>){5}", "<50>"); numbers = Regex.Replace(numbers, "(<10>){4}", "<40>"); numbers = Regex.Replace(numbers, "(<10>){3}", "<30>"); numbers = Regex.Replace(numbers, "(<10>){2}", "<20>"); numbers = Regex.Replace(numbers, "(<[0-9]{3}>)$", "$1<00>"); numbers = Regex.Replace(numbers, "(<[0-9]{2}>)$", "$1<0>"); numbers = Regex.Replace(numbers, "<([0-9]0)>\n", "$1\n"); numbers = Regex.Replace(numbers, "<([0-9])0*>", "$1"); System.Console.WriteLine(numbers); } } 

输出:

 # => 1 # => 2 # ... # => 99 # => 100 

方法A:

 Console.WriteLine('1'); Console.WriteLine('print 2'); Console.WriteLine('print 3'); ... Console.WriteLine('print 100'); 

方法B:

 func x (int j) { Console.WriteLine(j); if (j < 100) x (j+1); } x(1); 

只是LINQ它……

 Console.WriteLine(Enumerable.Range(1, 100) .Select(s => s.ToString()) .Aggregate((x, y) => x + "," + y)); 

我可以想两个方面:

  • 使用100 Console.WriteLine
  • switch语句中使用goto

完全不必要的方法:

 int i = 1; System.Timers.Timer t = new System.Timers.Timer(1); t.Elapsed += new ElapsedEventHandler( (sender, e) => { if (i > 100) t.Enabled = false; else Console.WriteLine(i++); }); t.Enabled = true; Thread.Sleep(110); 
 public void Main() { printNumber(1); } private void printNumber(int x) { Console.WriteLine(x.ToString()); if(x<101) { x+=1; printNumber(x); } } 

酷炫有趣的方式:

 static void F(int[] array, int n) { Console.WriteLine(array[n] = n); F(array, n + 1); } static void Main(string[] args) { try { F(new int[101], 1); } catch (Exception e) { } } 
 class Program { static int temp = 0; public static int a() { temp = temp + 1; if (temp == 100) { Console.WriteLine(temp); return 0; } else Console.WriteLine(temp); Program.a(); return 0; } public static void Main() { Program.a(); Console.ReadLine(); } } 
 PrintNum(1); private void PrintNum(int i) { Console.WriteLine("{0}", i); if(i < 100) { PrintNum(i+1); } } 
 namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Print(Enumerable.Range(1, 100).ToList(), 0); Console.ReadKey(); } public static void Print(List numbers, int currentPosition) { Console.WriteLine(numbers[currentPosition]); if (currentPosition < numbers.Count - 1) { Print(numbers, currentPosition + 1); } } } } 

这或多或少的伪代码我多年没做过c#,PS睡了1小时,所以我可能错了。

 int i = 0; public void printNum(j){ if(j > 100){ break; } else { print(j); printNum(j + 1); } } public void main(){ print(i); printNum(i + 1); } 

我的解决方案是在线程2045637中 ,它为Java提出了同样的问题。

 class Program { static Timer s = new Timer(); static int i = 0; static void Main(string[] args) { s.Elapsed += Restart; s.Start(); Console.ReadLine(); } static void Restart(object sender, ElapsedEventArgs e) { s.Dispose(); if (i < 100) { Console.WriteLine(++i); s = new Timer(1); s.Elapsed += Restart; s.Start(); } } } 

你必须注意到我没有使用递归。

感觉有点顽皮发布这个:

  private static void Main() { AppDomain.CurrentDomain.FirstChanceException += (s, e) => { var frames = new StackTrace().GetFrames(); Console.Write($"{frames.Length - 2} "); var frame = frames[101]; }; throw new Exception(); }