elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


  Mostrar Mensajes
Páginas: 1 ... 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [35] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ... 88
341  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de códigos C# (Compartan aquí sus códigos) en: 18 Julio 2015, 01:25 am
27 - Calcular el determinante de una matriz cuadrada de orden n

Voy a mostrar un código recursivo para calcular el determinante de una matriz cuadrada de orden n. No voy a explicar tan en detalle que cosa es el determinante pues son conocimientos "básicos" de algebra que deben saber si necesitan utilizar esté código.

Veamos que:

Sea A una matriz cuadrada; asociada a esa matriz hay un número llamado determinante, que se simboliza por |A| o det(A) y que se calcula de la siguiente forma:

- Si el orden de A es 2 el determinante es el producto de los elementos de la diagonal principal menos el producto de los elementos de la diagonal secundaria:

Ej:

A = (a00, a01)
      (a10, a11)

Luego: det(A) = a00*a11 - a10*a01

- Si el orden de A es 3 el determinante se calcula utilizando la llamada Regla de Sarrus, según la cual si A es la matriz de orden 3:

A = (a00, a01, a02)
      (a10, a11, a12)
      (a20, a21, a22)

y: det(A) = a00*a11*a22 + a01*a12*a20 + a02*a10*a21 - a02*a11*a20 - a01*a10*a22 - a00*a12*a21

Ahora, si el orden de la matriz es superior a 3 el determinante se reduce al de una matriz de orden 3 o de orden 2 de la siguiente manera (que es la que vamos a implementar):

A partir de la matriz cuadrada arbitraria A, si removemos la fila i y la columna j obtenemos una nueva matriz de orden (una unidad) menor que la matriz A y que la vamos a denotar como Aij, cuyo determinante det(Aij) recibe el nombre de menor complementario del elemento aij. Si a este det(Aij) le acompañamos de su signo (-1)i+j tenemos el adjunto de aij

Resumiendo:

Menor complementario de aij = det(Aij)
Adjunto de aij = cij = (-1)i+j*det(Aij)

Entonces, si A es una matriz cuadrada de orden mayor que 3 el determinante de A se obtiene eligiendo una fila o columna arbitraria de A y multiplicando a cada elemento de esta por su adjunto. De esta forma, si elegimos la fila i, el determinante de A es:

det(A) = SUMATORIA(desde i, j=1 hasta n)(aij * (-1)i+j * det(Aij))

Espero esto se haya entendido, trate de explicarlo lo más sencillo posible.

Ahora vamos al código:

Vamos a tener varios métodos con las siguientes signaturas:

Código
  1. public static int Determinant(int[,] matrix)
  2. static int DeterminantOrder2(int[,] matrix)
  3. static int DeterminantRec(int[,] matrix)
  4. static void FillMatrix(int[,] matrix, int[,] toFill, int row, int column)

Como podemos observar el método Determinant() va a ser el método portal, luego tenemos para calcular el determinante de una matriz de orden 2, luego para calcular el determinante de una matriz de orden mayor que 2 y el último es un método auxiliar para rellenar la matriz adjunta de los menores.

Código
  1. public static int Determinant(int[,] matrix)
  2.        {
  3.            //Comprobamos que sea cuadrada
  4.            if (matrix.GetLength(0) != matrix.GetLength(1))
  5.                throw new ArgumentException("La matriz debe ser cuadrada");
  6.            //Vemos si es de orden 2
  7.            if (matrix.GetLength(0) == 2)
  8.                return DeterminantOrder2(matrix);
  9.            else
  10.                return DeterminantRec(matrix);
  11.  
  12.        }

En este ^^ método lo primero que hacemos es comprobar que la matriz sea cuadrada, para esto comprobamos el valor del método .GetLength(), el cual devuelve un int que representa la cantidad de elementos en cada dimensión, o sea el orden de la matriz horizontal y vertical. En este caso tenemos dos dimensiones, por lo tanto comprobamos que si se cumple que:

Código
  1. matrix.GetLength(0) != matrix.GetLength(1)

Entonces lanzamos una excepción pues la matriz no es cuadrada.

Luego, ya que sabemos que la matriz es cuadrada vamos a comprobar si es de orden 2 y llamamos al método correspondiente, sino es de orden mayor y llamamos al método recursivo.

Veamos primero el método DeterminantOrder2():

Código
  1. static int DeterminantOrder2(int[,] matrix)
  2.        {
  3.            return (matrix[0, 0] * matrix[1, 1]) - (matrix[0, 1] * matrix[1, 0]);
  4.        }

Este método es muy sencillo lo cual no es necesario explicar nada. (Revisen arriba como se calcula el determinante de orden 2)

Ahora, vamos con el método DeterminatRec() que viene a ser "el más complicado", lo pongo entre comilla, porque no es más que una representación en código de la ecuación que les presenté antes para calcular el determinante de orden mayor que 2:

Código
  1. static int DeterminantRec(int[,] matrix)
  2.        {
  3.            //Caso de parada que sea de orden 2 y lo calculamos con el método para
  4.            //el determinante de orden 2
  5.            if (matrix.GetLength(0) == 2)
  6.            {
  7.                return DeterminantOrder2(matrix);
  8.            }
  9.            else
  10.            {
  11.                int det = 0; //Inicializamos una variable para almacenar el valor del determinante
  12.  
  13.                //En este ciclo recorremos una fila para para obtener el adjunto de cada elemento
  14.                //de esta fila así calcular el determinante de este fijando cada elemento de la fila
  15.                //0
  16.                for (int i = 0; i < matrix.GetLength(1); i++)
  17.                {
  18.                    //Creamos una matriz para rellenarla con la matriz para luego calcular su
  19.                    //determinante llamando recursivo. Esta matriz tiene un orden menor (en una
  20.                    //unidad) que la matriz original
  21.                    int[,] minor = new int[matrix.GetLength(0) - 1, matrix.GetLength(1) - 1];
  22.  
  23.                    //Aquí llamamos al método auxiliar que se encarga de rellenar la matriz auxiliar
  24.                    FillMatrix(matrix, minor, 0, i);
  25.  
  26.                    //Aquí lo que vamos a definir si lo que se hace es sumar o restar. Esto es una
  27.                    //manera de representar el cambio de signo que trae consigo el (-1) elevado a
  28.                    //i+j. En este caso como utilizamos la fila 0 siempre, ese número va a ser
  29.                    //positivo solo cuando estemos en una columna (j) que sea par, negativo en
  30.                    //caso contrario
  31.                    if (i % 2 == 0)
  32.                        //Aquí lo que hacemos es multiplicar el valor del elemento en cuestión
  33.                        //por el  adjunto teniendo en cuenta el signo correspondiente y se lo
  34.                        //sumamos a la variable det (en el else es lo mismo lo que con el signo
  35.                        //negativo). Aquí es donde está la llamada recursiva pues hay que calcular el
  36.                        //determinante de la matriz "minor"
  37.                        det+= (matrix[0, i]) * (DeterminantRec(minor));
  38.                    else
  39.                        det+= (-matrix[0, i]) * (DeterminantRec(minor));
  40.                }
  41.  
  42.                //Una vez que ya recorrimos toda la fila, devolvemos el determinante
  43.                return det;
  44.            }
  45.        }

Ya explique todo en los comentarios del código.

Ahora veamos el método FillMatrix():

Este método recibe la matriz desde la cual se van a sacar los valores, la matriz donde se van a copiar (de un orden menor en una unidad), la fila y la columna que se va a eliminar:

Código
  1. static void FillMatrix(int[,] matrix, int[,] toFill, int row, int column)
  2.        {
  3.            //Ciclo anidado para recorrer la matriz desde la cual se van a sacar los valores
  4.            for (int i = 0; i < matrix.GetLength(0); i++)
  5.            {
  6.                for (int j = 0; j < matrix.GetLength(1); j++)
  7.                {
  8.                    //Si estamos en una fila menor a la que se va a eliminar
  9.                    if (i < row)
  10.                    {
  11.                        //Si estamos en una columna menor a la que se va a eliminar
  12.                        if (j < column)
  13.                            toFill[i, j] = matrix[i, j]; //Copiamos el valor normalmente
  14.                        else
  15.                            if (j > column)
  16.                              //En este momento estamos en una fila menor a la que se va a
  17.                              //eliminar pero por encima de la columna a eliminar, por lo tanto
  18.                              //se saca el valor de la matriz y se coloca en una columna con una
  19.                              //unidad menos (j-1)
  20.                              toFill[i, j - 1] = matrix[i, j];
  21.                    }
  22.                    else
  23.                    //Si estamos en una fila mayor a la que se va a eliminar
  24.                    if (i > row)
  25.                    {
  26.                        //Si estamos en una columna mayor a la que se va a eliminar
  27.                        if (j < column)
  28.                            //En este momento estamos por encima de la fila a eliminar pero por debajo
  29.                            //de la columna a eliminar, por lo tanto tenemos que quitarle una unidad a la fila
  30.                            //(i-1)
  31.                            toFill[i - 1, j] = matrix[i, j];
  32.                        else
  33.                            if (j > column)
  34.                              //Aquí estamos por encima tanto de la fila como de la columna a eliminar por lo
  35.                              //tanto le quitamos una unidad tanto a las filas como a la columna (i-1, j-1)
  36.                              toFill[i - 1, j - 1] = matrix[i, j];
  37.                    }
  38.                }
  39.            }
  40.        }

Espero que este código se haya entendido, sino, ya saben que pueden preguntar, opinar y/o criticar.

Quizás no sea la mejor manera (complejidad temporal) de hacerlo, si tienen alguna sugerencia será bienvenida.

Espero seguir subiendo códigos pronto.

Salu2s
342  Programación / .NET (C#, VB.NET, ASP) / Re: Librería de códigos C# (Compartan aquí sus códigos) en: 18 Julio 2015, 01:20 am
26 - Evaluar una expresión en Notación Posfija (Notación Polaca Inversa)

Primero que todo, ¿Qué es la Notación Posfija (Notación Polaca Inversa)? Pues, es un método algebraico alternativo de introducción de datos, en está notación primero están los operandos y después viene el operador que se va a utilizar para realizar el cálculo sobre los operandos. En esta notación no se necesitan utilizar paréntesis para indicar el orden de las operaciones.

Veamos un ejemplo de notación posfija:

Código:
'4' '2' '10' '+' '*' '5' '-' = '43'

Para implementar esto, primero veamos el algoritmo que se utiliza:

Citar
-Si hay elementos en la bandeja de entrada
  -Leer el primer elemento de la bandeja de entrada.
    -Si el elemento es un operando.
      -Poner el operando en la pila.
    -Si no, el elemento es una función (los operadores, como "+", no son más que funciones que toman dos argumentos).
      -Se sabe que la función x toma n argumentos.
      -Si hay menos de n argumentos en la pila
        -(Error) El usuario no ha introducido suficientes argumentos en la expresión.
      -Si no, tomar los últimos n operandos de la pila.
      -Evaluar la función con respecto a los operandos.
      -Introducir el resultado (si lo hubiere) en la pila.
-Si hay un sólo elemento en la pila
  -El valor de ese elemento es el resultado del cálculo.
-Si hay más de un elemento en la pila
  -(Error) El usuario ha introducido demasiados elementos.

^^ Fuente: Wikipedia

En la implementación que hice, que estoy seguro, no es la mejor, solo tuve en cuenta los operadores +, -, *, /. Pueden añadirle más operadores para la raíz, potencia, etc.

Código
  1. static long EvalPosFixed(string[] exp)
  2.        {
  3.            Stack<long> values = new Stack<long>();
  4.            long first, second = 0;
  5.            for (int i = 0; i < exp.Length; i++)
  6.            {
  7.                switch (exp[i])
  8.                {
  9.                    case "+":
  10.                        if (values.Count < 2)
  11.                            throw new Exception("There are not enough arguments to operate");
  12.                        second = values.Pop();
  13.                        first = values.Pop();
  14.                        values.Push(first + second);
  15.                        break;
  16.                    case "-":
  17.                        if (values.Count < 2)
  18.                            throw new Exception("There are not enough arguments to operate");
  19.                        second = values.Pop();
  20.                        first = values.Pop();
  21.                        values.Push(first - second);
  22.                        break;
  23.                    case "*":
  24.                        if (values.Count < 2)
  25.                            throw new Exception("There are not enough arguments to operate");
  26.                        second = values.Pop();
  27.                        first = values.Pop();
  28.                        values.Push(first * second);
  29.                        break;
  30.                    case "/":
  31.                        if (values.Count < 2)
  32.                            throw new Exception("There are not enough arguments to operate");
  33.                        second = values.Pop();
  34.                        if (second == 0)
  35.                            throw new DivideByZeroException("Can't divide by 0");
  36.                        first = values.Pop();
  37.                        values.Push(first / second);
  38.                        break;
  39.                    default:
  40.                        values.Push(long.Parse(exp[i]));
  41.                        break;
  42.                }
  43.            }
  44.            if (values.Count > 1)
  45.                throw new Exception("The expression had more arguments than it should have");
  46.            return values.Peek();
  47.        }

El método no tiene nada complicado, recibe un array de string, el cual representa la expresión posfija, donde cada elemento del array representa un operando o un operador. En el método se recorre el array y se hace un switch para identificar los operadores. Lo demás se rige al algoritmo expuesto anteriormente.

Nota: No vuelvo a explicar el uso de una pila (Stack), pues ya lo expliqué en el código 22 - Saber si una cadena tiene paréntesis balanceados

Voy a ilustrarles, de cierta manera, el funcionamiento del algoritmo:

Supongamos que la entrada es:

Código
  1. string[] expresion = { "4", "2", "10", "+", "*", "5", "-"};

Luego:

EntradaOperaciónPilaComentario
4Introducir en la pila4
2Introducir en la pila4, 2
10Introducir en la pila4, 2, 10
+Suma4, 12Toma los dos últimos valores de la pila (2, 10) y los sustituye por el resultado (12)
*Multiplicación48Toma los dos últimos valores de la pila (4, 12) y los sustituye por el resultado (48)
5Introducir en la pila48 5
-Resta43Toma los dos últimos valores de la pila (48, 5) y los sustituye por el resultado (43)

Al finalizar, el resultado (en este caso 43) será el único elemento en la pila.

Espero que hayan entendido este código.

Salu2s
343  Foros Generales / Dudas Generales / Re: convertir 9c:97:26:d2:2f:a3 a texto en: 17 Julio 2015, 17:56 pm
¿A que te refieres con convertirlo a texto?

Salu2s
344  Programación / ASM / Re: ayuda plis en ensamblador en: 17 Julio 2015, 17:21 pm
Hola, el título debe ser descriptivo con respecto a tu problema.

También te quería decir que aquí no se hacen tareas y/o resuelven ejercicios, deberías intentar hacerlo y plantear las dudas puntuales que tengas. Estaremos más que dispuesto a ayudarte

Salu2s
345  Programación / Desarrollo Web / Re: [Ayuda] Problema con tamaño de ventana (posicionamiento css) en: 17 Julio 2015, 16:27 pm
¿Podrías poner una imagen de que es lo que pasa cuando redimensionas el navegador?

Salu2s
346  Programación / Programación C/C++ / Re: DUDA SOBRE ESTRUCTURAS REPETITIVAS EN ESTE PROBLEMA!! C++ en: 17 Julio 2015, 00:00 am
Las variables i, sum y sum2 tienes que inicializarlas dentro del while para que tengan su valor inicial por cada caso de prueba



Ahora, por la composición del problema, esto parece sacado de un juez en linea, por lo tanto, la manera de leer los datos no creo que sea la correcta, pues cuando te dicen:

Citar
La entrada consiste de varios casos de prueba hasta fin de archivo. Cada caso de prueba consiste en un número entero <= 1000.

No significa que hayan 1000 casos de prueba, sino que van a haber varios casos de prueba donde cada número que te entren va a ser menor o igual a 1000. Por lo tanto tu tienes que ir leyendo hasta el final del archivo los números e ir mostrando el resultado. Algo así como:

Código:
MIENTRAS NO FINAL DEL ARCHIVO
HACER
  INICIALIZAR VARIABLES
  LEER NUMERO
  REALIZAR LAS OPERACIONES
  DAR RESULTADO
FIN MIENTRAS

Espero que entiendas.

Salu2s
347  Foros Generales / Foro Libre / Re: Serias capaz de dar un organo por tu padre-madre? en: 16 Julio 2015, 18:00 pm
Muchos hijos dicen que por sus padres darían todo... ¿tu estaría dispuesto a dar un ORGANO a tu padre para salvarle la vida y que pueda durar muchos años mas? incluso darle la vida? sean sinceros...

Esta pregunta me surgio por que vi varios Twits diciendo que Nadie da la vida por nadie, y quiero saber...  :P


Yo creo que si lo daría, los padres son algo sagrado, imagina que sin ellos tu no existieras. Hace poco leí algo que me dejo pensando en que a veces no somos lo suficientemente buenos con ellos como deberíamos, o no lo demostramos, la linea decía así:

"Hijo, no te rías cuando no se utilizar el ordenador y te pido que me enseñes, recuerda que yo te enseñe a usar una cuchara"

No obstante, la cuestión creo que sería que tu padre/madre te permita dar un órgano por el/ella. Pues siendo padres, tienen el instinto natural de proteger a sus hijos, y creo que muchos no estarían de acuerdo con que su hijo se sacrificara de esa manera por ellos

Salu2s



@VBSH, estás haciendo doble post! Te recomiendo leer las reglas del foro:

foro.elhacker.net/reglas.htm
348  Programación / Programación Visual Basic / Re: ayuda con visual studio en: 16 Julio 2015, 16:58 pm
estoy empezando con la programacion y queria saber las diferencias entre
visual studio 2003. 2005. 2008. 2010 y 2012

Las diferencias son muchas, imagina cuanto puede cambiar un IDE en tantos años. Además, no solo el IDE, sino también los lenguajes, extensiones. Y sobre todo el Framework.

Nota: Te faltó el 2013 y 2015.

Salu2s
349  Foros Generales / Noticias / Re: Internet va cada vez más lento y no es solo por tu conexión en: 15 Julio 2015, 20:44 pm
Antiguamente también las conexiones eran con modem de 56K

Todavía esto existe aunque no en gran escala.

Por otro lado, todo esto depende de los diseñadores y/o creadores del sitio y sus "necesidades", pues para atraer a más visitantes pueden llegar a hacer de las páginas casi cualquier cosa, esto puede implicar mayor tamaño.

Salu2s

350  Programación / .NET (C#, VB.NET, ASP) / Re: [SOURCE] Snippet Tool Extension For Visual Studio (C#/VB) en: 15 Julio 2015, 19:24 pm
Vale :P, gracias.

Por curiosidad, ¿qué versión de VS utilizas?, me gustaría saber si la extensión se instala y funciona correctamente en VS2010, 2012 o 2015.

Utilizo VS2013, todavía no he querido dar el brinco a VS2015.

Salu2s
Páginas: 1 ... 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [35] 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ... 88
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines