简体   繁体   中英

How do I print the following pattern using 3 for loops instead of 4?

I'm trying to print the following pattern:

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

Now, I know how to do it using 4 for loops:

for(i=1;i<=n;i++)
{
    for(j=1;j<=i;j++)
    {
        cout<<"*";
    }
    cout<<"\n";
}

to print the first half and to print the second half:

for(i=1;i<=n;i++)
 {
    for(j=n;j>i;j--)
    {
        cout<<"*";
    }
     cout<<"\n";
}

Looking closely, both the outer for loops are the same. ie, for(i=1;i<=n;i++). Is there anyway to nest both the 'j' for-loops inside the i-for loop?

Using only one loop:

#include <iostream>
#include <string>

int main() {
   for (unsigned i = 0; i < 10; ++i)
      std::cout << std::string( i < 5 ? (i+1) : 10 - (i+1), '*') << std::endl;

   return 0;
}

Would you care for not even three loops, but just two loops?

int n=5, i, j, k;

for (i=0; i<n*2-1; i++)
{
   j=i;
   if (j >= n)
      j=n*2-2-j;

   for (k=0; k<=j; k++)
      std::cout << '*';
   std::cout << std::endl;
}

using 2 loops:

int g=1;
for(int i=0;i<=5;i++){
for (int y=0;y<=i;y+=g){
cout<<"*";
}

cout<<endl;

if (i==4 && g==1){
cout<<"*****";
i=3;
g=-1;
}}

Instead of printing 5 lines, and then another 5, you could print 10, and calculate the number of stars in each line.

for(i = 1; i <= 2*n - 1; i++)
{
    for(j = 1; j <= n - abs(i - n); j++)
        {
            cout<<"*";
        }
    cout<<"\n";
}

The expression n-abs(in) evaluates to i for values of i between 1 and n, and to 2n-i for values of i greater than n.

Just for fun, how about one loop:

  for (int i=1, j=0, dir=1; i!=0;) {
      cout << '*';
      ++j;

      if (j==i) {
          cout << '\n';
          j = 0;
          i += dir;

          if (i==6) {
              dir = -1;
              i -= 2;
          }
      }      
  }

You can do it in one loop (maybe cheating a little bit):

size_t max = 5;
size_t rows = max * 2 - 1;
std::string line(std::string(max, '*') + '\n');

for ( size_t j = 0, k = max; j < rows; ++j ) {
    std::cout << line.c_str() + ( j < max ? --k : ++k );
}

I know you didn't ask for it, but for completeness here's one with zero loops (recursion instead):

#include <iostream>

void print_stars(int count)
{
    if (count > 0)
    {
        std::cout << '*';
        print_stars(count - 1);
    }
}

void print_line(int lines, int stars)
{
    if (lines == 1)
        print_stars(stars);
    else
    {
        if (stars > 0)
        {
            print_stars(stars);
            std::cout << std::endl;
        }

        print_line(lines - 1, stars + 1);
        std::cout << std::endl;

        if (stars > 0)
            print_stars(stars);
    }
}

int main()
{
    int star_count = 5;
    print_line(star_count + 1, 0);
    return 0;
}

The pattern can be outputted using only one for loop.

Here is a demonstrative program.

#include <iostream>
#include <iomanip>

int main() 
{
    while ( true )
    {
        const char c = '*';

        std::cout << "Enter non-negative number (0 - exit): ";

        unsigned int n;

        if ( !( std::cin >> n ) || n == 0 ) break;

        std::cout << '\n';

        for ( unsigned int i = 1; i < 2 * n; i++ )
        {
            unsigned int w = i <= n ? i : 2 * n - i;

            std::cout << std::setfill( c ) << std::setw( w + 1 ) << '\n';
        }

        std::cout << std::endl;
    }

    return 0;
}

If to enter sequentially

5 4 3 2 1 0

then the program output will look the following way

Enter non-negative number (0 - exit): 5

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

Enter non-negative number (0 - exit): 4

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

Enter non-negative number (0 - exit): 3

*
**
***
**
*

Enter non-negative number (0 - exit): 2

*
**
*

Enter non-negative number (0 - exit): 1

*

Enter non-negative number (0 - exit): 0

Using the same variables of this well-structured program as function parameters you can write a separate function that outputs the pattern.

Here you are.

#include <iostream>
#include <iomanip>

std::ostream & pattern( unsigned int n, char c = '*', std::ostream &os = std::cout )
{
    for ( unsigned int i = 1; i < 2 * n; i++ )
    {
        unsigned int w = i <= n ? i : 2 * n - i;

        os << std::setfill( c ) << std::setw( w + 1 ) << '\n';
    }

    return os;
}

int main() 
{
    while ( true )
    {
        std::cout << "Enter non-negative number (0 - exit): ";

        unsigned int n;

        if ( !( std::cin >> n ) || n == 0 ) break;

        std::cout << '\n';

        pattern( n );       

        std::cout << std::endl;
    }

    return 0;
}

Take into account that for example it is a bad idea to use the standard class std::string to output the pattern because the program will be inefficient due to allocation and reallocation of the dynamic memory for an object of the class.

If not to use the standard stream manipulators then you can use standard algorithm std::fill_n to hide the inner loop. In this case the program also will have only one explicit loop.

For example

#include <iostream>
#include <algorithm>
#include <iterator>

int main() 
{
    while ( true )
    {
        const char c = '*';

        std::cout << "Enter non-negative number (0 - exit): ";

        unsigned int n;

        if ( !( std::cin >> n ) || n == 0 ) break;

        std::cout << '\n';

        for ( unsigned int i = 1; i < 2 * n; i++ )
        {
            unsigned int w = i <= n ? i : 2 * n - i;

            *std::fill_n( std::ostream_iterator<char>( std::cout ), w, c ) = '\n';
        }

        std::cout << std::endl;
    }

    return 0;
}
#include <iostream>
using namespace std;
int main() {
    int i;
    int j;
    int count = 1;
    for(i= 0;i<10;i++) {
        if(i < 5) {
           for(j=0;j<=i;j++) {
               cout<<"*";
           }
        } else {
           for(j=i-count;j>0;j--) {
              cout<<"*";
           } 
           count +=2;
    }
       cout<< "\n";
   }
   return 0;
}

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