使用c++的菱形恒星

Stars rhombus using c++

本文关键字:恒星 c++ 使用      更新时间:2023-10-16

如何使用最少的循环和变量在c++中输出菱形的以下星号。最大星数=n(从用户处输入)

  *
 * *
* * * = n
 * * 
  *

我试着只用两个循环,但没有成功,而且程序太复杂,无法理解,所以这里没有包含它。

你能想到什么算法吗?

那不是金字塔,那是菱形:)

不管怎样,让我们看看星号:

  • n=1->1星
  • n=2->4星
  • n=3->9颗星

该模式看起来是从1到n减去n的总和的两倍(因为中间一行存在一次而不是两次),所以s(n) = 2 * (1+n)/2 * n - n = (1+n)*n-n=n*n嘿,这是一个正方形的面积!多么令人惊讶。:-)

现在如何绘制n大小的菱形:

  • 将有2*n-1
  • 每行宽度为w = 2*n-1个字符
  • 每个第i行(从i=0开始)都有m = min(i+1, 2*n-1-i)恒星,它们之间有m-1空间
  • 所以每一行需要w - (m) - (m-1)个边上的空间填充空间,即w/2在左边和右边

现在去写吧!:)

我相信这是一个常见的教育问题,因此谷歌搜索非常有用。

这里有一个现成的Visual C++解决方案(有些人从代码示例中学习得更好,您可以选择)。。。

http://www.softwareandfinance.com/Visual_CPP/Loops_Diamond_Pattern.html

编辑:试图减少for循环并保持恒星之间的间距,这是我最大的努力。。。

int i, j;
int n = 0;
std::cout << "Enter the maximum number of *:";
std::cin >> n;
std::cout << "nn";
for (i = 1; i <= n; i++)
{
      std::cout.width(n - i);
      std::cout.fill(' ');
      std::cout << "";
      for (j = 1; j <= i; j++)
            std::cout << "* ";
      std::cout.width(n - i);
      std::cout.fill(' ');
      std::cout << "";
      std::cout << "n";
}
for (i = n - 1; i >= 1; i--)
{
      std::cout.width(n - i);
      std::cout.fill(' ');
      std::cout << "";
      for (j = 1; j <= i; j++)
            std::cout << "* ";
      std::cout.width(n - i);
      std::cout.fill(' ');
      std::cout << "";
      std::cout << "n";
}
std::cout << "n";

仅使用2个循环

int i, j;
int n = 0, c = 0, inc = 1;
std::cout << "Enter the maximum number of *:";
std::cin >> n;
std::cout <<"nn";
for (i = 1; i <= (n * 2) - 1; i++)
{
    c += inc;
    if(i == n)
        inc = -1;
    std::cout.width(n - c);
    std::cout.fill(' ');
    std::cout << "";
    for (j = 1; j <= c; j++)
        std::cout << "* ";
    std::cout.width(n - c);
    std::cout.fill(' ');
    std::cout << "";
    std::cout <<"n";
}
std::cout <<"n";

两个循环?你肯定只需要一个就可以过得去。。以下是对我提出的算法的粗略描述:

  • 循环通过(2*n-1)^2平方
  • 确定当前行所需的星数(即到有n颗星的行的距离)
  • 确定与当前索引中间的距离
  • 如果当前索引的绝对距离小于该行上的恒星数量,则它需要奇数/偶数索引中的一颗恒星,这取决于n是否为奇数/偶数
  • 添加行末尾的端线

这是一个几乎值得IOCC快速即兴创作的算法,它用两个变量绘制菱形,循环计数器和n=中间一行的恒星数量。

#include <cmath>
void print_rhombus(int n) 
{
    for (int i = 1; i <= ((2*n-1)*(2*n-1)); ++i) {        
        if ((abs((((2*n-1)+1)/2)-(i%(2*n-1) == 0?2*n-1:i%(2*n-1)))) - (n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n)) < 0 && (
                (n%2==1 && ((n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n))%2==1 && (i%(2*n-1) == 0?2*n-1:i%(2*n-1))%2 == 1 || (n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n))%2==0 && (i%(2*n-1) == 0?2*n-1:i%(2*n-1))%2==0)) || 
                (n%2==0 && ((n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n))%2==1 && (i%(2*n-1) == 0?2*n-1:i%(2*n-1))%2 == 0 || (n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n))%2==0 && (i%(2*n-1) == 0?2*n-1:i%(2*n-1))%2==1))
                )) {
            std::cout << "*"; 
        } else { 
            std::cout << " "; 
        } 
        if (i%(2*n-1) == 0 && (n-abs((i%(2*n-1)==0?(i/(2*n-1)):(i/(2*n-1))+1) - n)) == n) {
            std::cout << " = " << n << std::endl; 
        }
        else if (i%(2*n-1) == 0) { 
            std::cout << std::endl; 
        }
    }    
}

它还打印"=N",我想这可能不是要求。正如你所看到的,有时几个额外的描述性变量会起到很大的作用。如果这是家庭作业,你最好准备好解释一下。

分解任务。

1) 首先编写一个程序,输出一个正方形的星号。在上面的例子中(我认为n=3),一个五乘五的正方形将包含您想要输出的所有星号。两个循环(一个在另一个内部)就是这样做的方法。

2) 现在你有了所有你需要的星号,计算出应该跳过哪些星号才能得到你想要的菱形图案的公式。如果您决定跳过星号,则输出一个空格。

所有的编程都是这样的,你面临着一个复杂的问题,你把它分解成更小的子问题。

像这样的未填充菱形:

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

代码c++:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int w=7;
    int h=7;
    string fill("*");
    string empty(" ");
    for (int i = 0; i<w; i++)
    {
        for (int j = 0; j<h; j++)
        {
            if((j == h/2-i) or (j == h/2+i) or (j == -h/2+i) or (j+i == h+h/2-1) ) cout << fill;
            else cout <<empty;
        }
        cout<<endl;
        
    }
}