我正在寻找输出n以及小于(n *(n + 1))/ 2的循环次数的输出,
示例N = 4,
1
2 3
4 5 6
7 8 9 10
循环次数应小于10。 这可能吗???
答案 0 :(得分:2)
还有一个只有一个循环的解决方案。
按顺序打印数字,后跟空格,如果最后一个数字是triangular,则打印换行符。跟踪你有多少新行,以及它。
以下是代码:
public static void PrintPyramid(int n)
{
var i = 0;
while (n > 0)
{
Console.Write(++i);
if (IsTriangularNumber(i))
{
Console.Write(Environment.NewLine);
n--;
}
else
{
Console.Write(" ");
}
}
}
public static bool IsTriangularNumber(int i)
{
var n = (int)Math.Sqrt(i*2);
return n*(n + 1) / 2 == i;
}
以下是它的工作原理:http://ideone.com/Mx7Cel
有关更快的三角数测试,请参阅this question的答案。
答案 1 :(得分:2)
通过作弊很容易:
n == 4
我做了一个小循环展开,在同一个循环中最多做两个数字。对于public static void PrintPyramid3(int n)
{
if (n >= 1)
{
Console.Write("1");
Console.Write(" ");
Console.WriteLine();
}
int i = 2;
int row = 2;
int maxNumberInRow = 3;
int cycles = 0;
while (row <= n)
{
cycles++;
Console.Write(i);
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
}
else
{
Console.Write(" ");
}
}
Console.WriteLine();
Console.WriteLine("Cycles: {0}", cycles);
}
,它是6个完整周期。
请注意,如果我们想要玩语义游戏,部分循环展开就足够了:
n == 4
第一行是循环的“外部”,因此对于x
,只需要9个循环。
基于此代码,可以轻松部分循环展开第一个public static void PrintPyramid(int n)
{
PrintPyramidRecursive(n, 1, 1, 1);
}
private static void PrintPyramidRecursive(int n, int i = 1, int row = 1, int maxNumberInRow = 1)
{
Console.Write(i);
Console.Write(" ");
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
if (row > n)
{
return;
}
}
PrintPyramidRecursive(n, i, row, maxNumberInRow);
}
个案例,并在循环中完成剩余的案例。
好的......我在开玩笑......有可能以完全无环的方式做到这一点......
public static void PrintPyramid5(int n)
{
int i = 1;
int row = 1;
int maxNumberInRow = 1;
ManualResetEvent mre = new ManualResetEvent(false);
Timer t = null;
TimerCallback tc = x =>
{
Console.Write(i);
Console.Write(" ");
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
if (row > n)
{
t.Dispose();
mre.Set();
}
}
};
t = new Timer(tc, null, 0, 1);
mre.WaitOne();
}
你只需要使用递归! :-) :-): - )
这个有点狡猾:没有(明显的)周期而且没有递归:
Timer
简单地说,打印方法由tc
调用:-)所以循环在操作系统中。对于n == 4
,打印方法(div {
width: 200px;
height: 150px;
background: red;
-webkit-clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
clip-path: polygon(20% 10%, 85% 30%, 100% 100%, 0% 100%);
}
)显然会被调用10次。
答案 2 :(得分:1)
您可以假装string.Join()
和Enumerable.Range()
不在内部进行任何循环,并按照以下方式执行:
int n = 4;
for (int i = 1, j = 1; i <= n; ++i, j += i-1)
Console.WriteLine(string.Join(" ", Enumerable.Range(j, i).Select(x => x.ToString("00"))));
for
循环因此每行只循环一次而不是每个输出数循环一次。但这是一种欺骗,因为string.Join()
和Enumerable.Range()
在内部进行循环。
根据xanatos的建议,这里是一个没有显式循环的版本:
Console.WriteLine(
string.Join("\n", Enumerable.Range(1, n).Select(i =>
string.Join(" ", Enumerable.Range((i*(i-1))/2+1, i).Select(x =>
x.ToString("00"))))));
当然,这只是一种好奇心。 ;)
最后,这是xanatos的递归解决方案的变体:
private static string Triangular(int max, int row, int rowEnd, int number)
{
if (row == max)
return "";
else if (number <= rowEnd)
return number.ToString("00") + " " + Triangular(max, row, rowEnd, number + 1);
else
return "\n" + Triangular(max, row + 1, rowEnd + row + 1, number);
}
您可以这样使用:
Console.WriteLine(Triangular(n, 1, 1, 1));
答案 3 :(得分:0)
这里我做了你的功课
public static void PrintPyramid(int n)
{
int t = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
Console.Write(t);
t++;
}
Console.WriteLine();
}
}