英文:
how can I do an empty triangle with stars in c++ to after do the british flag?
问题
这是我必须在最后获得的标志:
*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************
我知道如何制作满星的三角形,但当内部为空时,我不知道该如何继续。有人能帮帮我吗?
我尝试过,我只知道如何制作满星的三角形和内部为空的星形正方形/矩形,以下是代码:
int main(void)
{
    int i, j, length, width;
    cout << "矩形的长度? ";
    cin >> length;
    cout << endl;
    cout << "矩形的宽度? ";
    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;
}
英文:
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;
}
答案1
得分: 0
中间放置十字很容易:
if (i == ??? || j == ???)
    std::cout << '*';
else
    std::cout << ' ';
对角线稍微复杂一些。
在你的嵌套循环中,打印 std::cout << (i+j) << '\t'。你能看出这些数字中是否有任何模式,可以让你识别出其中一个对角线吗?
然后,用 i-j 重复相同的步骤。你能看出另一个对角线的模式吗?
最终,你的嵌套循环将如下所示:
if (i == /*某个条件*/ || j == /*某个其他条件*/ || (i+j) .../*某个条件*/ || (i-j) .../*另一个条件*/)
    std::cout << '*';
else
    std::cout << ' ';
英文:
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 i-j. 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 << ' ';
答案2
得分: 0
第1、10和19行很容易,因为它们每行都只包含19个星号。
问题在于第2到9行和第11到19行。
不过,你是否注意到第2到9行存在一种模式?
第2行由一个星号组成,
- 后跟0个空格
 - 后跟一个星号
 - 后跟7个空格
 - 后跟一个星号
 - 后跟7个空格
 - 后跟一个星号
 - 后跟0个空格
 
后跟一个星号
第3行由一个星号组成,
- 后跟1个空格
 - 后跟一个星号
 - 后跟6个空格
 - 后跟一个星号
 - 后跟6个空格
 - 后跟一个星号
 - 后跟1个空格
 
后跟一个星号。
第4行由一个星号组成,
- 后跟2个空格
 - 后跟一个星号
 - 后跟5个空格
 - 后跟一个星号
 - 后跟5个空格
 - 后跟一个星号
 - 后跟2个空格
 
后跟一个星号。
第5行由一个星号组成,
- 后跟3个空格
 - 后跟一个星号
 - 后跟4个空格
 - 后跟一个星号
 - 后跟4个空格
 - 后跟一个星号
 - 后跟3个空格
 
后跟一个星号。
第6行由一个星号组成,
- 后跟4个空格
 - 后跟一个星号
 - 后跟3个空格
 - 后跟一个星号
 - 后跟3个空格
 - 后跟一个星号
 - 后跟4个空格
 
后跟一个星号。
第7行由一个星号组成,
- 后跟5个空格
 - 后跟一个星号
 - 后跟2个空格
 - 后跟一个星号
 - 后跟2个空格
 - 后跟一个星号
 - 后跟5个空格
 
后跟一个星号。
第8行由一个星号组成,
- 后跟6个空格
 - 后跟一个星号
 - 后跟1个空格
 - 后跟一个星号
 - 后跟1个空格
 - 后跟一个星号
 - 后跟6个空格
 
后跟一个星号。
第9行由一个星号组成,
- 后跟7个空格
 - 后跟一个星号
 - 后跟0个空格
 - 后跟一个星号
 - 后跟0个空格
 - 后跟一个星号
 - 后跟7个空格
 
后跟一个星号。
模式如下:
假设size是三角形的总大小(在你的情况下是19),那么
第n行由一个星号组成,
- 后跟n-2个空格
 - 后跟一个星号
 - 后跟(size/2) - n个空格
 - 后跟一个星号
 - 后跟(size/2) - n个空格
 - 后跟一个星号
 - 后跟n-2个空格
 
后跟一个星号。
请注意,在C中,19 / 2的结果是9,因为除法的小数部分被舍弃。
使用这个有关模式的信息,你应该能够创建一个循环,每次循环迭代时打印一行如上所述的内容。这样,你应该能够解决打印第2到第9行的问题。
之后,打印第11到第19行应该很容易,因为这些行只需要以第2到第9行的相反顺序打印出来。
英文:
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 
0spaces - followed by one 
* - followed by 
7spaces - followed by one 
* - followed by 
7spaces - followed by one 
* - followed by 
0spaces 
followed by one *
Line 3 consists of one *
- followed by 
1spaces - followed by one 
* - followed by 
6spaces - followed by one 
* - followed by 
6spaces - followed by one 
* - followed by 
1spaces 
followed by one *.
Line 4 consists of one *
- followed by 
2spaces - followed by one 
* - followed by 
5spaces - followed by one 
* - followed by 
5spaces - followed by one 
* - followed by 
2spaces 
followed by one *.
Line 5 consists of one *
- followed by 
3spaces - followed by one 
* - followed by 
4spaces - followed by one 
* - followed by 
4spaces - followed by one 
* - followed by 
3spaces 
followed by one *.
Line 6 consists of one *
- followed by 
4spaces - followed by one 
* - followed by 
3spaces - followed by one 
* - followed by 
3spaces - followed by one 
* - followed by 
4spaces 
followed by one *.
Line 7 consists of one *
- followed by 
5spaces - followed by one 
* - followed by 
2spaces - followed by one 
* - followed by 
2spaces - followed by one 
* - followed by 
5spaces 
followed by one *.
Line 8 consists of one *
- followed by 
6spaces - followed by one 
* - followed by 
1spaces - followed by one 
* - followed by 
1spaces - followed by one 
* - followed by 
6spaces 
followed by one *.
Line 9 consists of one *
- followed by 
7spaces - followed by one 
* - followed by 
0spaces - followed by one 
* - followed by 
0spaces - followed by one 
* - followed by 
7spaces 
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-2spaces - followed by one 
* - followed by 
(size/2) - nspaces - followed by one 
* - followed by 
(size/2) - nspaces - followed by one 
* - followed by 
n-2spaces 
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' );
    }
}
答案3
得分: 0
不要翻译代码部分,以下是翻译好的内容:
"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."
上面的代码打印出:
*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************
英文:
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:
*******************
**       *       **
* *      *      * *
*  *     *     *  *
*   *    *    *   *
*    *   *   *    *
*     *  *  *     *
*      * * *      *
*       ***       *
*******************
*       ***       *
*      * * *      *
*     *  *  *     *
*    *   *   *    *
*   *    *    *   *
*  *     *     *  *
* *      *      * *
**       *       **
*******************
答案4
得分: 0
以下是翻译好的部分:
示例(基于我在30多年前学过的2D计算机图形课程的知识)。使用1D向量(动态分配的数组)作为内存缓冲区和Bresenham的线算法
在线演示: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) // 分配缓冲区并清零
    {
        assert(width > 1);
        assert(height > 1);
        int w = width - 1;
        int h = height - 1;
        // 标志的轮廓
        line(0, 0, w, 0);
        line(w, 0, w, h);
        line(w, h, 0, h);
        line(0, h, 0, 0);
        // 对角线
        line(0, 0, w, h);
        line(0, h, w, 0);
        // 中线,水平和垂直
        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线算法
    // 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;
    // 用于保存m_grid的每个位置的真假的缓冲区
    // 想象像素 ;)
    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;
}
英文:
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;
}
答案5
得分: -1
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;
    }
}
英文:
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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论