Print edges of a c ++ matrix

3

Community, I ask for your help with a small problem. I'm just learning C ++ and I've been working with arrays and arrays, I understand the logic of how to print a matrix and how it goes through its contents, but there are things that I can not solve yet. The following code shows how an array of AxA is printed (with the value 0) per terminal, where A is an input received by keyboard.

#include <iostream> 
using namespace std;

int main( ) {
  while( 1 ) {
    int a = 0;
    int i = 0;
    int j = 0;

    cout << "Ingresa dimensiones del cuadrado" << endl;
    cin >> a;

    if( cin.fail( ) ) {
      cout << "Input incorrecto" << endl;
      cin.clear( );
      cin.ignore( );
    } else {
      for( i = 1; i <= a; i++ ) {
        for( j = 1; j <= a; j++ ) {
          cout << " o ";
        }
        cout << endl;
      }
    }       
  }
}

If the value of A is 4, you should print what appears in the image-point 1. However, I need only print the edges , that is, if the value of A is 4, the result should be the one seen in the image-point 2

This rule must be met for any value of a.

Thank you very much

    
asked by E. Vargas 05.04.2017 в 20:16
source

3 answers

6

What you need is for a visible element to be printed when the rows or columns have their maximum or minimum value, an element that is not visible otherwise.

Proposal.

std::string si(" o "), no("   ");

for(i = 1; i <= a; i++ ) {
    for(j = 1; j <= a; j++ ) {
        cout << (i == 1 || j == 1 || i == a || j == a ? si : no);
    }
    cout << endl;
}

To be taken into account.

In general, it is not advised to use using namespace std; , see this question to know why.

On the other hand, the use of std::endl can lead to performance problems because it empties the buffer; although in a program as simple as yours it will not be a problem. See this question for more details.

    
answered by 06.04.2017 / 09:00
source
3

Since in C ++ the indexes start at 0 you should consider modifying your loops to work in the interval (0..a-1) instead of (1..a). It's more natural and reduces the chances of making mistakes by mixing both ranges.

Well, if we assume that you have modified the loops then the edges should be painted under the following conditions:

  • i==0
  • i==a-1
  • j==0
  • j==a-1

And the effect could be achieved with something such that:

for( int i = 0; i < a; i++ ) {
  for( int j = 0; j < a; j++ ) {
    if( i==0 || i==a-1 || j==0 || j==a-1 )
      std::cout << " o";
    else
      std::cout << "  ";
  }
  std::cout << std::endl;
}

The 4 checks could be reduced to two if we use the rest:

for( int i = 0; i < a; i++ ) {
  for( int j = 0; j < a; j++ ) {
    if( i%(a-1) == 0 || j%(a-1)==0 )
      std::cout << " o";
    else
      std::cout << "  ";
  }
  std::cout << std::endl;
}

You could even improve a little bit more if reverse logic is applied to the above:

for( int i = 0; i < a; i++ ) {
  for( int j = 0; j < a; j++ ) {
    if( i%(a-1) && j%(a-1) )
      std::cout << "  ";
    else
      std::cout << " o";
  }
  std::cout << std::endl;
}

Now, the if is like a goop. It can be deleted quietly using a small array and from the library iomanip :

const char relleno[] = { 'o', ' ' };

// ...

std::cout << std::setfill(' ');
for( int i = 0; i < a; i++ ) {
  for( int j = 0; j < a; j++ ) {
    std::cout << std::setw(2) << relleno[i%(a-1) && j%(a-1)];
  }
  std::cout << std::endl;
}
    
answered by 06.04.2017 в 08:59
1

You could try adding in the second for, a check to know if it is an edge, or if it is a value in the center of the drawing.

if (j = 1 || j = a)
    cout << " o ";
else
    cout << "   ";

To this you would have to add that check that it is not the first row or the last row, because if they are all painted.

    
answered by 05.04.2017 в 20:32