Catching elements around a selected array

7

The idea is to create an array of integers with the amount of rows and columns defined by the user. Then an existing value in the array must be entered and the program should return the values immediately to the left, right, above and below the array.

Example

Número de Linhas: 3
Número de Colunas: 4

10 7 15 12
21 11 23 8
14 5 13 19 

Número que deseja verificar: 11

Esquerda: 21
Direita: 23
Acima: 7
Abaixo: 5

The code I developed works perfectly when you insert an array value that is not in the 'corner'. If I enter a value that is in the 'corner' the program throws the System.IndexOutOfRangeException exception indicating that there are no values immediately above / left / down / right of the desired value.

How could I handle this exception? Any tips are welcome since my goal is to learn. Here's my code for review.

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] Linha = Console.ReadLine().Split(' ');
            int[,] Numeros = new int[int.Parse(Linha[0]), int.Parse(Linha[1])];

            for (int i = 0; i < int.Parse(Linha[0]); i++)
            {
                string[] vet = Console.ReadLine().Split(' ');
                for (int j = 0; j < int.Parse(Linha[1]); j++)
                {
                    Numeros[i, j] = int.Parse(vet[j]);
                }
            }

            string[] Localizacao = new string[4];
            int Num = int.Parse(Console.ReadLine());
            for (int i = 0; i < int.Parse(Linha[0]); i++)
            {
                for (int j = 0; j < int.Parse(Linha[1]); j++)
                {
                    if (Numeros[i, j] == Num)
                    {
                        Localizacao[0] = Numeros[i, j - 1].ToString();
                        Localizacao[1] = Numeros[i, j + 1].ToString();
                        Localizacao[2] = Numeros[i - 1, j].ToString();
                        Localizacao[3] = Numeros[i + 1, j].ToString();
                    }
                }
            }

            Console.WriteLine("Esquerda: " + Localizacao[0]);
            Console.WriteLine("Direita: " + Localizacao[1]);
            Console.WriteLine("Acima: " + Localizacao[2]);
            Console.WriteLine("Abaixo: " + Localizacao[3]);

            Console.ReadLine();
        }
    }
}
    
asked by anonymous 30.08.2018 / 16:26

2 answers

6

The first point is to avoid entering data in the current form. And test the input data because you can type wrong. I left this form unintuitive, but tested for typos.

The same error is that if the data to be searched is in the row or column 0 or is in the final row or column at the moment it reaches -1 the index will be -1 and when it reaches +1 it takes a value higher than exists, and gives error. So what I did is that I just show the existing sides and left blank what does not exist.

using static System.Console;

public class Program {
    public static void Main() {
        string[] linha = ReadLine().Split(' ');
        int linhas;
        if (!int.TryParse(linha[0], out linhas)) return;
        int colunas;
        if (!int.TryParse(linha[1], out colunas)) return;
        int[,] numeros = new int[linhas, colunas];
        for (int i = 0; i < linhas; i++) {
            string[] vet = ReadLine().Split(' ');
            for (int j = 0; j < colunas; j++) {
                int valor;
                if (!int.TryParse(vet[j], out valor)) return;
                numeros[i, j] = valor;
            }
        }
        string[] localizacao = new string[4];
        int num;
        if (!int.TryParse(ReadLine(), out num)) return;
        for (int i = 0; i < linhas; i++) {
            for (int j = 0; j < colunas; j++) {
                if (numeros[i, j] == num) {
                    localizacao[0] = j == 0 ? "" : numeros[i, j - 1].ToString();
                    localizacao[1] = j == numeros.GetUpperBound(1) ? "" : numeros[i, j + 1].ToString();
                    localizacao[2] = i == 0 ? "" : numeros[i - 1, j].ToString();
                    localizacao[3] = i == numeros.GetUpperBound(0) ? "" : numeros[i + 1, j].ToString();
                }
            }
        }
        WriteLine("Esquerda: " + localizacao[0]);
        WriteLine("Direita: " + localizacao[1]);
        WriteLine("Acima: " + localizacao[2]);
        WriteLine("Abaixo: " + localizacao[3]);
    }
}

See running on .NET Fiddle . And no Coding Ground . Also I placed GitHub for future reference .

    
30.08.2018 / 16:50
5

The problem is that some indexes are exceeding the limits of Array , either for more (more than the maximum index) or for less (-1).

The solution will be to validate everything before assigning the value to Localizacao :

if (Numeros[i, j] == Num)
{
    if(j - 1 >= 0)
        Localizacao[0] = Numeros[i, j - 1].ToString();
    else
    {
        // código de controlo
    }

    if(j + 1 < Linha[1])
        Localizacao[1] = Numeros[i, j + 1].ToString();
    else
    {
        // código de controlo
    }

    if(i - 1 >= 0)
        Localizacao[2] = Numeros[i - 1, j].ToString();
    else
    {
        // código de controlo
    }

    if(i + 1 < Linha[0])
        Localizacao[3] = Numeros[i + 1, j].ToString();
    else 
    {
        // código de controlo
    }
}

The código de controlo is where you should place the instruction to use when the maximum or minimum limit is reached.

If the goal is to display a message if the indexes are exceeded, you can do the following:

if (Numeros[i, j] == Num)
{
    if(j - 1 >= 0 || j + 1 < Linha[1] || i - 1 >= 0 || i + 1 < Linha[0])
    {
        MessageBox.Show("Os índices da matriz foram excedidos.");
    }
    else
    {
        Localizacao[0] = Numeros[i, j - 1].ToString();
        Localizacao[1] = Numeros[i, j + 1].ToString();
        Localizacao[2] = Numeros[i - 1, j].ToString();
        Localizacao[3] = Numeros[i + 1, j].ToString();
    }
}

There are also two interesting methods for validating the boundaries of an array: GetLength :

int[,] Numeros = new int[2, 3];

int x = Numeros.GetLength(0);   // devolve 2
int y = Numeros.GetLength(1);   // devolve 3
    
30.08.2018 / 16:38