Operaciones con matrices

English version of this post.
Hace algún tiempo se me presentaron algunos problemas de algoritmos comunes relacionados con las matrices, hoy acabo de encontrar algo de código en mi máquina virtual de Windows y pensé que sería una buena idea publicarlo aquí sólo para mantenerlo en línea.

Recuerdo que estaba en busca de un algoritmo para imprimir una matriz cuadrada en espiral, y me encontré con algo de código en el Internet como de costumbre, que utiliza un buen approach, tuve que modificarlo porque estaba en otro lenguaje y necesitaba que estuviera en C#,

Bueno, aquí está la clase que hice con el approach de Internet, la clase es compatible con la multiplicación de matrices cuadradas y también es compatible con la impresión de una matriz cuadrada en espiral utilizando un approach recursivo indirecto.

Matrices.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace Samples
{
    public static class Matrices
    {
        public static double[,] MtxMult(double[,] mtxA, double[,] mtxB)
        {
            if (mtxA == null || mtxA.Length == 0)
                throw new ArgumentException("Array parameter must be valid");
     
            if (mtxB == null || mtxB.Length == 0)
                throw new ArgumentException("Array parameter must be valid");
  
            if (mtxA.Length != mtxB.Length)
                throw new ArgumentException("Arrays must have the same length");
  
            int size = mtxA.GetLength(0); // get first dimmension lenght
            double[,] mtxC = new double[size, size];
            for (int i = 0; i < size; i++)
                for (int j = 0; j < size; j++)
                {
                    // Compute dot product of row i and column j.
                    for (int k = 0; k < size; k++)
                        mtxC[i, j] += mtxA[i, k] * mtxB[k, j];
                }
                 
            return mtxC;
        }
 
        private static IList<int> _spiralMtx = null;
        public static IList<int> MtxProcessSpiral(int[,] mtx)
        {
            _spiralMtx = null;
            _spiralMtx = new List<int>();
            int x1 = 0;
            int y1 = 0;
            int x2 = mtx.GetLength(0) - 1;
            int y2 = mtx.GetLength(1) - 1;
            MtxProcessTopRight(mtx, x1, y1, x2, y2);
            return _spiralMtx;
        }
 
        //
        // prints the top and right shells of the matrix
        //
        private static void MtxProcessTopRight(int[,] mtx, int x1, int y1, int x2, int y2)
        {
            int i = 0; 
            int j = 0;
            // print the row
            for (i = x1; i <= x2; i++)
                _spiralMtx.Add(mtx[y1, i]);
             
            //print the column 
            for (j = y1 + 1; j <= y2; j++)
                _spiralMtx.Add(mtx[j, x2]);
             
            // see if we have more cells left
            if (x2 - x1 > 0 && y2 - y1 > 0)
            {
                // 'recursively' call the function to print the bottom-left layer
                MtxProcessBottomLeft(mtx, x1, y1 + 1, x2 - 1, y2);
            }
        }
 
        //
        // prints the bottom and left shells of the matrix
        //
        private static void MtxProcessBottomLeft(int[,] mtx, int x1, int y1, int x2, int y2)
        {
            int i = 0;
            int j = 0;
            // print the row of the matrix in reverse
            for (i = x2; i >= x1; i--)
                _spiralMtx.Add(mtx[y2, i]);
 
            // print the last column of the matrix in reverse
            for (j = y2 - 1; j >= y1; j--)
                _spiralMtx.Add(mtx[j, x1]);
 
            if (x2 - x1 > 0 && y2 - y1 > 0)
            {
                // 'recursively' call the function to print the top-right layer
                MtxProcessTopRight(mtx, x1 + 1, y1, x2, y2 - 1);
            }
        }
    } 
}

¡Saludos! 🙂
-Yohan

Leave a Reply

Your email address will not be published. Required fields are marked *