Get the elements around a selected in the matrix

Asked

Viewed 440 times

8

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

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 entering a matrix value that is not in the 'corner'. If I enter a value that is in the 'corner' the program throws the exception System.IndexOutOfRangeException indicating that there are no values immediately above/left/below/right of the desired value.

How could I treat this exception? Any tips are welcome since my goal is to learn. Follow my code for analysis.

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();
        }
    }
}
  • This exception usually occurs when an instruction attempts to access an element at an index greater than the maximum allowed index.

  • Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site

3 answers

8


The first point is to avoid entering data in the current form. And test the entered data because it may 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 picks up -1 the index will be -1 and when it picks up +1 it picks up a value above what exists, and gives error. So what I’ve done is I’ve shown only the existing sides and left blank what doesn’t 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]);
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

  • Thank you for your help. There are plenty of methods and classes in your code that I have to give a studied to fully understand.

  • Yes, and if you don’t do this the code will behave wrong. I actually think only 2 methods and probably 1 operator. One of them may stop using because you already have the information, but I found it interesting to know.

6

The problem is that some indices are exceeding the limits of Array, either more (more than the maximum index) or 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 be used when the limit, maximum or minimum, is reached.

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

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 to validate the boundaries of a matrix: GetLength:

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

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

-2

In order for the program to respect the example shown, in addition to sanitizing user inputs, the program can be done as follows:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    public class Program
    {
        private static class Vector
        {
            public static bool TryParse(string input, int columns, out IEnumerable<int> decodedValues)
            {
                var list = new List<int>();
                bool result = false;

                string[] sanity = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);

                if (sanity.Length != columns)
                {
                    result = false;
                }
                else if (sanity.All(entry => int.TryParse(entry, out int dummy)))
                {
                    result = true;
                    list.AddRange(sanity.Select(entry => int.Parse(entry)));
                }

                decodedValues = list;
                return result;
            }
        }

        public static void Main(string[] args)
        {
            var (lines, columns) = GetLinesAndColumns();
            var matrix = GetMatrix(lines, columns).ToArray();
            var selectedValue = GetSelectedValue();

            DisplayNorthSouthEastWest(selectedValue, matrix, lines, columns);
        }

        public static (int, int) GetLinesAndColumns()
        {
            string input = null;
            int lines;
            int columns;

            do
            {
                Console.Write("Número de linhas: ");
                input = Console.ReadLine();
            } while (!int.TryParse(input, out lines));

            do
            {
                Console.Write("Número de colunas: ");
                input = Console.ReadLine();
            } while (!int.TryParse(input, out columns));

            Console.WriteLine();

            return (lines, columns);
        }

        public static IEnumerable<int> GetMatrix(int lines, int columns)
        {
            string input = null;
            IEnumerable<int> result = null;
            for (int i = 0; i < lines; ++i)
            { 
                do
                {
                    Console.Write($"    {i+1}: ");
                    input = Console.ReadLine();
                } while (!Vector.TryParse(input, columns, out result));

                foreach (var item in result)
                {
                    yield return item;
                }
            }

            Console.WriteLine();
        }

        public static int GetSelectedValue()
        {
            string input = null;
            int selectedValue;
            do
            {
                Console.Write("Número que deseja verificar: ");
                input = Console.ReadLine();
            } while (!int.TryParse(input, out selectedValue));

            Console.WriteLine();

            return selectedValue;
        }

        public static void DisplayNorthSouthEastWest(int selectedValue, int[] matrix, int lines, int columns)
        {
            var vector = matrix.ToArray();

            int selectedIndex = Array.FindIndex(vector, item => item == selectedValue);

            if (selectedIndex < 0)
            {
                Console.WriteLine($"Número que deseja verificar, {selectedValue}, não está na matriz.");
            }
            else
            { 
                int temp;
                int north = selectedIndex - columns;
                int south = selectedIndex + columns;
                int west  = (temp = selectedIndex) % columns == 0       ? -1 : temp - 1;
                int east  = (temp = (selectedIndex + 1)) % columns == 0 ? -1 : temp;

                string northString = north < 0 ?              "Não há" : vector[north].ToString();
                string southString = south >= vector.Length ? "Não há" : vector[south].ToString();
                string westString  = west < 0 ?               "Não há" : vector[west].ToString();
                string eastString  = east < 0 ?               "Não há" : vector[east].ToString();

                Console.WriteLine($"Esquerda : {westString}");
                Console.WriteLine($"Direita  : {eastString}");
                Console.WriteLine($"Acima    : {northString}");
                Console.WriteLine($"Abaixo   : {southString}");
            }
        }
    }
}
  • 1

    I could edit the reply and insert a description of your reply?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.