简体   繁体   中英

create asterisk tree with C#

Hello everyone I try to solve asterisk tree problem and found my code is not work correctly and can be improved.

This is output that expected

input : 5

    *
  * * *
* * * * *
  * * *
    *

input : 4

* * * *
  * *
* * * *

and this is my code

static void Main(string[] args)
        {
            Console.Write("input:");

            char input = Console.ReadKey().KeyChar;

            if (char.IsDigit(input))
            {
                int couter = (int)char.GetNumericValue(input);

                Console.WriteLine();

                if (couter % 2 != 0)
                {

                    for (int i = 1; i <= couter; i++)
                    {

                        for (int j = 3; j > i; j--)
                        {

                            Console.Write("  ");

                        }

                        for (int k = 1; k <= i; k++)
                        {

                            Console.Write(" *");

                        }

                        Console.WriteLine();
                    }

                    for (int i = couter - 1; i >= 3; i--)
                    {
                        for (int j = 1; j <= i; j++)
                        {

                            if (j <= couter - i)
                            {
                                Console.Write("  ");
                            }
                            else
                            {
                                Console.Write("* ");
                            }
                        }

                        Console.WriteLine();
                    }

                }
                else
                {

                    for (int i = couter; i > 3; i--)
                    {
                        for (int j = 1; j <= i; j++)
                        {
                            if (couter - i >= j)
                            {
                                Console.Write("  ");
                            }
                            else
                            {
                                Console.Write("* ");
                            }
                        }

                        Console.WriteLine();


                    }

                    for (int i = couter - 1; i <= couter; i++)
                    {
                        for (int j = 0; j < i; j++)
                        {
                            Console.Write("* ");
                        }

                        Console.WriteLine();
                    }
                }

            }
        }

Please could you help me to solve this problem.

Lately, I think I'm poor at algorithms and a little complex problem. Is anybody know useful link or how I can improve this skill, please let me know.

Thanks,

Check this page for input 5 (diamond) : http://www.dreamincode.net/forums/topic/126715-diamond-asterisk/

I've translated it to C# - now it displays diamonds with size that you set in variable 'rows':

int rows = 5;
StringBuilder sb = new StringBuilder();
// top part
for (int i = 1; i <= rows; i++)
{
    for (int j = 1; j <= rows - i; j++)
        sb.Append(' ');
    for (int k = 1; k <= 2 * i - 1; k++)
        sb.Append('*');
    sb.AppendLine();
}
//bottom part
for (int n = rows - 1; n > 0; n--)
{
    for (int l = 1; l <= rows - n; l++)
        sb.Append(' ');
    for (int m = 1; m <= 2 * n - 1; m++)
        sb.Append('*');
    sb.AppendLine();
}
Console.Write(sb.ToString());

I was initially reluctant to post it because it definitely smells like homework...

Anyway, here's a piece of working code:

static void Main(string[] args)
{
    Console.Write("input:");

    char input = Console.ReadKey().KeyChar;

    if (char.IsDigit(input))
    {
        int couter = (int)char.GetNumericValue(input);
        Console.WriteLine();
        if (couter % 2 != 0)
            PrintDiamond(couter);
        else
            PrintHourGlass(couter);
    }
    Console.ReadLine();
}

private static void PrintDiamond(int couter)
{
    bool moreAsterisks = true;
    for (int row = 0; row < couter; row++)
    {
        int nAsterisks = moreAsterisks ? (2 * row) + 1 : 2 * (couter - row - 1) + 1;
        int nSpaces = (couter - nAsterisks) / 2;

        if (row == (couter - 1) / 2)
            moreAsterisks = false;

        for (int i = 0; i < nSpaces; i++)
            Console.Write(" ");
        for (int i = 0; i < nAsterisks; i++)
            Console.Write("*");
        for (int i = 0; i < nSpaces; i++)
            Console.Write(" ");
        Console.WriteLine();
    }
}

private static void PrintHourGlass(int couter)
{
    bool moreAsterisks = false;
    for (int row = 0; row < couter - 1; row++)
    {
        int nAsterisks = moreAsterisks ? couter - 2 * (couter - row - 2) : couter - (2 * row);
        int nSpaces = (couter - nAsterisks) / 2;

        if (row == (couter - 2) / 2)
            moreAsterisks = true;

        for (int i = 0; i < nSpaces; i++)
            Console.Write(" ");
        for (int i = 0; i < nAsterisks; i++)
            Console.Write("*");
        for (int i = 0; i < nSpaces; i++)
            Console.Write(" ");
        Console.WriteLine();
    }
}

PS : it works with any number, not just 4-5...

Here's a minified LINQ solution for your problem:

    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("input: ");
            string line = Console.ReadLine();

            int n;
            if (!int.TryParse(line, out n))
            {
                Console.WriteLine("Enter a valid integer number.");
                return;
            }

            for (int i = 0; i < n; i++)
            {
                int l = Math.Abs(n - i * 2 - 1) + 1;
                if (n % 2 != 0) l = n - l + 1;

                Console.Write(Enumerable.Repeat(" ", n - l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
                Console.WriteLine(Enumerable.Repeat("* ", l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
            }
        }
    }

It's pretty simple; inside the loop, first line calculates length of the i-th diamond row if input is even, second one corrects the calculation for odd input. The remaining two lines print i-th row using some LINQ tricks. If you don't like showing off with LINQ, you can replace thoose lines with regular for loops (which is probably going to be faster). Then the code would look like:

class Program
{
    static void Main(string[] args)
    {
        Console.Write("input: ");
        string line = Console.ReadLine();

        int n;
        if (!int.TryParse(line, out n))
        {
            Console.WriteLine("Enter a valid integer number.");
            return;
        }

        for (int i = 0; i < n; i++)
        {
            int l = Math.Abs(n - i * 2 - 1) + 1;
            if (n % 2 != 0) l = n - l + 1;

            //Console.Write(Enumerable.Repeat(" ", n - l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
            //Console.WriteLine(Enumerable.Repeat("* ", l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
            for (int c = 0; c < n - l; c++) Console.Write(" ");
            for (int c = 0; c < l; c++) Console.Write("* ");
            Console.WriteLine();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM