使用较少的循环在C#中打印数字序列

时间:2015-08-13 12:20:04

标签: c# loops for-loop

我正在寻找输出n以及小于(n *(n + 1))/ 2的循环次数的输出,

示例N = 4,

1

2 3

4 5 6

7 8 9 10

循环次数应小于10。 这可能吗???

4 个答案:

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