简体   繁体   中英

how can I do an empty triangle with stars in c++ to after do the british flag?

This is the flag that I have to get at the end:

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

I know how to do full star triangles but when it's empty on the inside I have no idea about how to proceed. Can anyone help me?

I tried and I just know how to do full star triangles and a star square/rectangle empty on the inside here is the code:

int main(void)
{
    int i, j, length, width;

    cout << "Length of rectangle? ";
    cin >> length;
    cout << endl;

    cout << "Width of rectangle? ";
    cin >> width;
    cout << endl;

    for ( i = 0; i < length; i++ )
        cout << "*";

    cout << endl;

    for ( i = 1; i < width - 1; i++ )
    {
        cout << "*";

        for ( j = 1; j < length - 1; j++ )
        {
            cout << " ";
        }

        cout << "*";
        cout << endl;
    }

    for ( i = 0; i < length; i++)
        cout << "*";

    cout << endl;

    return 0;
}

Getting the cross in the middle is easy:

if (i == ??? || j == ???)
    std::cout << '*';
else
    std::cout << ' ';

The diagnoals are slightly more tricky.

In your nested loop, print std::cout << (i+j) << '\t' . Do you see any pattern in the numbers that lets you identify one of the diagonals?

Then repeat the same thing with ij . Do you see the pattern for the other diagonal?

In the end, your nested loop will look like this:

if (i == /*something*/ || j == /*something else*/ || i+j .../*some condition*/ || i-j .../*another condition*/)
    std::cout << '*';
else
    std::cout << ' ';

Lines 1 , 10 and 19 are easy, as they each consist only of 19 * .

The problem is the lines 2 to 9 and 11 to 19 .

However, do you notice a pattern in lines 2 to 9 ?

Line 2 consists of one *

  • followed by 0 spaces
  • followed by one *
  • followed by 7 spaces
  • followed by one *
  • followed by 7 spaces
  • followed by one *
  • followed by 0 spaces

followed by one *

Line 3 consists of one *

  • followed by 1 spaces
  • followed by one *
  • followed by 6 spaces
  • followed by one *
  • followed by 6 spaces
  • followed by one *
  • followed by 1 spaces

followed by one * .

Line 4 consists of one *

  • followed by 2 spaces
  • followed by one *
  • followed by 5 spaces
  • followed by one *
  • followed by 5 spaces
  • followed by one *
  • followed by 2 spaces

followed by one * .

Line 5 consists of one *

  • followed by 3 spaces
  • followed by one *
  • followed by 4 spaces
  • followed by one *
  • followed by 4 spaces
  • followed by one *
  • followed by 3 spaces

followed by one * .

Line 6 consists of one *

  • followed by 4 spaces
  • followed by one *
  • followed by 3 spaces
  • followed by one *
  • followed by 3 spaces
  • followed by one *
  • followed by 4 spaces

followed by one * .

Line 7 consists of one *

  • followed by 5 spaces
  • followed by one *
  • followed by 2 spaces
  • followed by one *
  • followed by 2 spaces
  • followed by one *
  • followed by 5 spaces

followed by one * .

Line 8 consists of one *

  • followed by 6 spaces
  • followed by one *
  • followed by 1 spaces
  • followed by one *
  • followed by 1 spaces
  • followed by one *
  • followed by 6 spaces

followed by one * .

Line 9 consists of one *

  • followed by 7 spaces
  • followed by one *
  • followed by 0 spaces
  • followed by one *
  • followed by 0 spaces
  • followed by one *
  • followed by 7 spaces

followed by one * .

The pattern is the following:

Assuming that size is the total size of the triangle (which is 19 in your case), then

line n consists of one *

  • followed by n-2 spaces
  • followed by one *
  • followed by (size/2) - n spaces
  • followed by one *
  • followed by (size/2) - n spaces
  • followed by one *
  • followed by n-2 spaces

followed by one * .

Note that in C, the result of 19 / 2 is 9 , as the fractional part of the division is discarded.

Using this information about the pattern, you should be able to create a loop that in every loop iteration, prints one line as described above. That way, you should be able to solve the problem of printing the lines 2 to 9 .

Printing the lines 11 to 19 should be easy afterwards, because these lines must only be printed in reverse order of the lines 2 to 9 .

In accordance with the community guidelines for homework questions , I will not provide the full solution at this time. I can provide further information later, if necessary.

EDIT:

Since several other solutions have already been posted by other users, I will now also post my solution, which solves the problem as described above:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    //print first horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print top half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print second horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';

    //print bottom half of flag
    for ( int i = 0; i < MAP_SIZE / 2 - 1; i++ )
    {
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < i; j++ )
            std::cout << ' ';
        std::cout << '*';
        for ( int j = 0; j < MAP_SIZE/2 - 2 - i; j++ )
            std::cout << ' ';
        std::cout << '*';
        std::cout << '\n';
    }

    //print third horizontal line
    for ( int i = 0; i < MAP_SIZE; i++ )
        std::cout << '*';
    std::cout << '\n';
}

However, I think that this problem is easier to solve using a 2D array (which you stated that you are not allowed to use). The 2D array is initialized to spaces and then the 3 horizontal, 3 vertical and 2 diagonal lines are drawn:

#include <iostream>

const int MAP_SIZE = 19;

static_assert( MAP_SIZE % 2 == 1, "MAP_SIZE must be odd" );

int main( void )
{
    char map[MAP_SIZE][MAP_SIZE];

    //initialize 2D array to spaces
    for ( int i = 0; i < MAP_SIZE; i++ )
        for ( int j = 0; j < MAP_SIZE; j++ )
            map[i][j] = ' ';

    //draw the 3 horizontal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[         0][i] = '*';
        map[MAP_SIZE/2][i] = '*';
        map[MAP_SIZE-1][i] = '*';
    }

    //draw the 3 vertical lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][         0] = '*';
        map[i][MAP_SIZE/2] = '*';
        map[i][MAP_SIZE-1] = '*';
    }

    //draw the 2 diagonal lines
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        map[i][           i] = '*';
        map[i][MAP_SIZE-i-1] = '*';
    }

    //print the result
    for ( int i = 0; i < MAP_SIZE; i++ )
    {
        std::cout.write( map[i], MAP_SIZE );
        std::cout.put( '\n' );
    }
}

Instead of calculating each line in a loop. Have a function return what to draw at each point. Then you can apply some basic algebra to decide if there's a point to draw.

#include <iostream>

char getPoint(int width, int height, int x, int y) {
    int xNorm = (x <= width / 2) ? x : (width - x);
    int yNorm = (y <= height / 2) ? y : (height - y);

    // borders
    if ( ((x == 0) || (x == (width)) || (y == 0) || (y == height)) ||  // borders
         ((x == width / 2) || (y == height / 2)) ||                    // middle stripe
         ((width >= height) && (yNorm == xNorm * height / width)) ||   // diagnols (when width >= height)
         ((height > width) && (xNorm == yNorm * width / height))       // diagnols (when height > width)
        )
    {
        return '*';
    }
    return ' ';
}

void printFlag(int width, int height) {
    for (int y = 0; y <= height; y++) {
        for (int x = 0; x <= width; x++) {
            std::cout << getPoint(width, height, x, y);
        }
        std::cout << std::endl;
    }
}

int main()
{
    int height = 18;
    int width = 18;
    printFlag(width, height);
    return 0;
}

The above prints:

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

Example (based on knowledge from 2D computer graphics course I had over 30 years ago). Using a 1D vector (dynamically allocated array) as memory buffer and the Bresenham's line algorithm

Live demo here: https://onlinegdb.com/Kg9HAdxfZ

#include <cassert>
#include <iostream>
#include <vector>

class Flag
{
public:
    Flag(int width, int height) :
        m_width{ width },
        m_height{ height },
        m_grid(width*height,false) // allocate buffer and clear to false
    {
        assert(width > 1);
        assert(height > 1);

        int w = width - 1;
        int h = height - 1;

        // outline of flag
        line(0, 0, w, 0);
        line(w, 0, w, h);
        line(w, h, 0, h);
        line(0, h, 0, 0);

        // diagonals
        line(0, 0, w, h);
        line(0, h, w, 0);

        // mid lines horizontal and vertical
        line(0, h / 2, w, h / 2);
        line(w / 2, 0, w / 2, h);
    };

    bool get(int x, int y) const
    {
        return m_grid.at(y * m_width + x);
    }

    int width() const noexcept
    {
        return m_width;
    }

    int height() const noexcept
    {
        return m_height;
    }

private:
    void set(int x, int y)
    {
        m_grid.at(y * m_width + x) = true;
    }

    // Bresenham's line algorithm 
    // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
    void line(int x0, int y0, int x1, int y1)
    {
        int dx = abs(x1 - x0);;
        int sx = x0 < x1 ? 1 : -1;
        int dy = -abs(y1 - y0);
        int sy = y0 < y1 ? 1 : -1;
        int error = dx + dy;

        while (true)
        {
            set(x0, y0);
            if ((x0 == x1) && (y0 == y1)) break;

            int e2 = 2 * error;
            if (e2 >= dy)
            {
                if (x0 == x1) break;
                error = error + dy;
                x0 = x0 + sx;
            }
            if (e2 <= dx)
            {
                if (y0 == y1) break;
                error = error + dx;
                y0 = y0 + sy;
            }
        }
    }

private:
    int m_width;
    int m_height;
    
    // a buffer to hold true/false for each posision of the m_grid
    // think pixels ;)
    std::vector<bool> m_grid;
};

std::ostream& operator<<(std::ostream& os, const Flag& flag)
{
    for (int y = 0; y < flag.height(); ++y)
    {
        for (int x = 0; x < flag.width(); ++x)
        {
            if (flag.get(x, y))
            {
                os << "*";
            }
            else
            {
                os << " ";
            }
        }
        std::cout << "\n";
    }
    
    return os;
}

int main()
{
    Flag flag(47, 15);
    std::cout << flag;
    return 0;
}
void DrawUKflag(int L, int W)
{

    for (int i = 0; i <=L; i++)
    {
        for (int k = 0; k <=W; k++) 
        {
            if (i==0||i==L/2||i==L ||k==0||k==W/2||k==W)
            {
                cout << "*";
            }
            else if (k==W-i || k==i)
            {
                cout << "*";
            }
            else
            {
                cout << " ";
            }
        }
        cout << endl;
    }
}

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