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

 

 


Tema destacado: Estamos en la red social de Mastodon


  Mostrar Mensajes
Páginas: 1 [2] 3
11  Programación / Java / Diferentes formas de manejar eventos en java. en: 25 Marzo 2019, 00:07 am
Buenas a todos , tenía la curiosidad sobre saber cual era su forma de organizar las clases destinadas a las interfaces gráficas y en especifico como administraban el objeto que respondía a los eventos.

Actualmente he visto 2 formas muy particulares de hacerlo y que las mostrare con un ejemplo sencillo que tiene 3 botones, cada botón hace referencia a un color y cuando se da clic en alguno de ellos simplemente el panel se pinta de dicho color.

1ra Forma. El panel al ser el objeto que va ser afectado por el evento es el que implementa la interfaz ActionListener.

Código
  1. import java.awt.*;
  2. import java.awt.Color;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5.  
  6. public class Manejo{
  7.    public static void main(String[] args) {
  8.        Ventana v1 = new Ventana(new Dimension(400,400));
  9.        v1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  10.    }
  11.  
  12.  
  13. }
  14.  
  15.  
  16. class Ventana extends JFrame{
  17.    Lamina l1;
  18.    public Ventana(Dimension d){
  19.        setSize(d);
  20.        l1 = new Lamina();
  21.        add(l1);
  22.        setVisible(true);
  23.    }
  24.  
  25.  
  26. }
  27.  
  28. class Lamina extends JPanel implements ActionListener{
  29.    private JButton verde;
  30.    private JButton azul;
  31.    private JButton amarillo;
  32.    private Color fondo;
  33.  
  34.    public Lamina(){
  35.        verde = new JButton("Color verde");
  36.        azul = new JButton("Color azul");
  37.        amarillo = new JButton("Color amarillo");
  38.  
  39.        verde.addActionListener(this);
  40.        azul.addActionListener(this);
  41.        amarillo.addActionListener(this);
  42.        add(verde);
  43.        add(azul);
  44.        add(amarillo);
  45.    }
  46.  
  47.    @Override
  48.    public void actionPerformed(ActionEvent e){
  49.        Object fuente = e.getSource();
  50.  
  51.        if(fuente  == verde){
  52.            fondo = Color.GREEN;
  53.            setBackground(fondo);
  54.  
  55.        }else if( fuente == azul){
  56.            fondo = Color.BLUE;
  57.            setBackground(fondo);
  58.  
  59.        }else{
  60.            fondo = Color.YELLOW;
  61.            setBackground(fondo);
  62.  
  63.        }
  64.    }
  65.  
  66. }

2da Forma. Se crea una clase anidada que controla el evento e implementa la interfaz actionListener .

Código
  1. import java.awt.*;
  2. import java.awt.Color;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5.  
  6. public class Manejo{
  7.    public static void main(String[] args) {
  8.        Ventana v1 = new Ventana(new Dimension(400,400));
  9.        v1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  10.    }  
  11. }
  12.  
  13.  
  14. class Ventana extends JFrame{
  15.    Lamina l1;
  16.    public Ventana(Dimension d){
  17.        setSize(d);
  18.        l1 = new Lamina();
  19.        add(l1);
  20.        setVisible(true);
  21.    }
  22.  
  23.  
  24. }
  25.  
  26. class Lamina extends JPanel {
  27.    private JButton verde;
  28.    private JButton azul;
  29.    private JButton amarillo;
  30.    private Color fondo;
  31.  
  32.    public Lamina(){
  33.        verde = new JButton("Color verde");
  34.        azul = new JButton("Color azul");
  35.        amarillo = new JButton("Color amarillo");
  36.  
  37.        verde.addActionListener(new ColorFondo(Color.GREEN));
  38.        azul.addActionListener(new ColorFondo(Color.BLUE));
  39.        amarillo.addActionListener(new ColorFondo(Color.YELLOW));
  40.  
  41.        add(verde);
  42.        add(azul);
  43.        add(amarillo);
  44.    }
  45.  
  46.  
  47.    private class ColorFondo implements ActionListener{
  48.        private Color c;
  49.  
  50.        public ColorFondo(Color c){
  51.            this.c = c;
  52.        }
  53.  
  54.        @Override
  55.        public void actionPerformed(ActionEvent e){
  56.            setBackground(c);
  57.        }
  58.  
  59.    }
  60.  
  61. }
  62.  


A partir de las anteriores formas de dar solución al problema me causa la incógnita el saber cual podría ser la mejor forma de hacerlo, personalmente no encuentro mucha diferencia para inclinarme hacia un lado pero me gustaría saber si alguien pudiera compartir su experiencia y explicar cual prefiere y la razón del por que.


12  Programación / Programación C/C++ / Re: programacion de grafos en: 23 Marzo 2019, 05:39 am
Creo que para comenzar debes pensar en como representar un grafo dentro de tu programa. Debido a que este programa no necesita el peso de los vértices de un grafo te puede bastar con algo llamado matriz de adyacencia u otra forma seria una lista de adyacencia que es algo cercano a la matriz de adyacencia pero sin embargo solo almacena valores para los nodos con adyacencia... Personalmente creo que la matriz de adyacencia es la más facil tanto de implementar como de entender.

En resumen la matriz de adyacencia es una matriz cuadrada de longitud igual al numero de nodos en donde  cada uno de sus valores puede tener solo dos valores(booleano) , un valor true determina que existe adyacencia mientras que un valor false determina que no existe adyacencia, es decir, no existe conexión entre esos dos vertices.

Ejemplo de matriz de adyacencia de la imagen:
011000
100110
100010
010011
011101
000110

En pocas palabras la primera fila representa las conexiones o adyacencias con otros vértices a partir del vértice '1' o del primer vértice, la segunda fila representa las conexiones con otros vértices a partir del vértice '2' o del segundo vértice y así sucesivamente.
Nota. La matriz de adyacente tiene ambigüedades pensando en que se trata de un grafo no dirigido por lo cual es redundante representar la conexión de A->B y B->A .


En resumen la anterior matriz de adyacencia representa:

1. El vertice 1 tiene adyacencia con el vertice 2 y 3.
2. El vertice 2 tiene adyacencia con el vertice 1,4 y 5.
3. El vertice 3 tiene adyacencia con el vertice 1 y 5.
4. El vertice 4 tiene adyacencia con el vertice 2,5 y 6.
5. El vertice 5 tiene adyacencia con el vertice 2,3,4 y 6.
6. El vértice 6 tiene adyacencia con el vértice 4 y 5.

Es importante tomar en cuenta que en C++ los arreglos comienzan en el indice 0 por lo cual podríamos decir que la fila n representa la adyacencia  del vértice n+1.
Ejemplo
Matriz_Adyacencia[ 0 ][ . . . ] representa un valor de adyacencia del vértice 1 ( 0 +1 )

A partir de lo anterior ya podrías empezar a aplicar el algoritmo debido a que ya tienes la representación del grafo, en el problema se plantea el uso de una cola la cual no es necesario que revises a detalle su implementación debido a que ya existe una clase definida en C++ la cual puedes utilizar aunque personalmente yo recomendaría ver ese tipo de temas antes de llegar al tema de grafos.

    



13  Programación / Programación C/C++ / Re: programacion de grafos en: 21 Marzo 2019, 15:13 pm
Sugiero una correccion a la explicacion anterior: donde dice 'pila' cambiar por 'cola'
Listo. Una disculpa por el descuido.
14  Programación / Programación C/C++ / Re: programacion de grafos en: 21 Marzo 2019, 07:05 am
Buenas , no soy un experto en el área pero personalmente en este tipo de algoritmos me ayuda mucho el realizar una prueba de escritorio o pensar el algoritmo antes de irme al código. Para dar inicio al problema es importante saber que es lo que se intenta realizar con este algoritmo. El algortimo de bfs esta hecho para hacer un recorrido a partir de un nodo inicial por cada uno de los nodos de un grafo de manera que cuando llegamos a cada uno de estos nodo nosotros podemos procesarlo , en este caso escribirlo en pantalla.El recorrido de anchura también es conocido como recorrido por niveles , este es un punto importante para entenderlo. Yo lo consideraría como una jerarquía en una empresa. Tenemos 1 jefe, 4 subjefes y finalmente 5 empleados. El objetivo es llegar con cada personal empezando por el jefe, primero vamos a visitar al jefe, después a un subjefe, después al 2do subjefe, después al 3ro..... y asi sucesivamente hasta terminar con los subjetefes, una vez terminada la visita de los subjefes seguiría la visita de cada uno de los empleados.
Ojo. El algortimo va determinar el orden que en el que se van a visitar los miembros de cada subnivel , lo importante es entender que primero visitamos a todos los nodos(personas) del mismo nivel , una vez que terminamos con un nivel nos vamos a visitar a los del siguiente nivel y asi sucesivamente...

Ahora aterrizando esta idea en la teoría de grafos.... Tenemos un grafo como el que nos presentas en el cual queremos partir de un nodo para hacer un recorrido por amplitud. Lo primero es ver cual es el nivel mas "cercano" a este grafo, en otras palabras, ¿Que nodos son adyacentes al inicial?, Va... En este momento debemos considerar que no queremos procesar dos veces a un mismo nodo por lo cual podriamos llevar un control(un arreglo) que nos permita saber que nodos ya han sido visitados.

Pasos.
1. Empezamos en el nodo 1.
2. La bandera que corresponde al visitado del nodo 1 se activa.
3. Metemos al nodo 1 en una cola.
4. Empieza un ciclo que continuara mientras la cola no este vacía.
     5. Sacas un nodo de la cola.
     6. Lo procesas(Escribes en pantalla)
     7. Metes todos sus adyacentes a este nodo asegurandote que ninguno de ellos hayan sido visitados anteriormente. (OJO. Cuando agregas algún nodo adyacente debes activar su correspondiente bandera que permita saber que ya fue visitado, es decir, que ya fue ingresado en algun momento a la cola).
8.Fin_Ciclo de paso 4

De esta manera la cola nos va determinar la secuencia con la que vamos a procesar cada nodo y si nos ponemos a pensar esto no es tan dificil de ver, al fin de cuenta lo que estamos haciendo es meter los elementos en la cola por niveles de adyacencia. Primero metemos los nodos que se encuentran en el primer nivel de adyacencia, despues metemos los nodos con el siguiente nivel de adyacencia y asi sucesivamente de manera que la cola nos va ir generando la salida de manera que el primero que entro va ser el primero que va salir , es decir, el primer nivel de nodos que entro va ser el primer nivel de nodos que va ser procesado.

Una vez analizando un poco el algoritmo ya puedes considerar hacer una primera implementación del código en algún lenguaje de programación, tu siguiente paso es programarlo y ver que parte aún causa problemas.

15  Programación / Programación C/C++ / Re: Contenedores estandar en C++ en: 7 Marzo 2019, 19:54 pm
Ok, gracias. Creo que mi error es pensar en la estructuras de datos de la forma en las que yo las he implementado dejando a un lado que no importa su implementacion si no que presente una interfaz o metodos que le permitan comportarse como una pila , una cola,etc.
16  Programación / Programación C/C++ / Re: Contenedores estandar en C++ en: 7 Marzo 2019, 18:21 pm
Muchas gracias por tu respuesta, solo para complementar menciono que la información que menciono fue recolectada del libro "TADs, Estructuras de datos y resolucion de problemas con C++" 2da. Version del autor Larry R. Nyhoff. De antemano agradeceria si alguien conoce un mejor libro de estructuras de datos enfocado en el lenguaje de c++ de preferencia.
17  Programación / Programación C/C++ / Contenedores estandar en C++ en: 7 Marzo 2019, 05:29 am
Buenas a todos,estaba comenzando a ver las especificaciones que tienen los contenedores estandar en c++ tales como deque,queue,stacks y me tope con que el autor menciona incialmente como esta implementado el contenedor deque en c++,mencionando que realmente no seria una implementación del todo adecuada a un estructura 'deque' debido a que en el fondo contiene un vector map que permite la interfaz de una pila doble. A partir de lo anterior menciona que el contenenedor 'stack' es realmente un contenedor que puede tener en su interior otro contenedor como list,queue o vector y que realmente stack lo único que proporciona es una interfaz que simula una pila pero que realmente tiene otro contenedor dentro de el. Finalmente menciona que el contenedor 'queue' realmente contiene un contenedor 'deque' con el cual finalmente interactua para proporcionar un contenedor que se comporte como una cola.

Con respecto a lo anterior me surge la incognita de si esto succede en la mayoria de los lenguajes, realmente no logro visualizar que tan buena pueda ser la desicion de componer a los contenedores de esta forma pero me crea la duda debido a que anteriormente yo visualizaba a estas clases como la tipica lista ligada o vector que interactuaba como una cola con un cierto numero de nodos,etc. Mas que poner en duda sobre la buena/mala implementacion de dichos contenedores me gustaria simplemente saber que tan habitual o comun es toparte con lenguajes que tengan una implementacion parecida.
18  Programación / Programación C/C++ / Re: Preservacion del contenido de la memoria en contra de tiempo de vida de variable en: 7 Marzo 2019, 05:16 am
Ojo, que la pila sigue ahí, ya que fue reservada al inicio del programa. La pila sólo es liberada al finalizar el programa.
Mientras no finalice el programa tú puntero conserva la referencia al primer elemento de la pila (ver ejemplo del tercer punto).

De antemano muchas gracias por tu tiempo , todo lo que anteriormente me mencionaste me ayudo mucho sin embargo aún sigo poniendo en duda esta parte. Entiendo que inicialmente el programa se incia en el main con lo cual en la pila se encuentra la funcion main con el respectivo almacenamiento de su variables sin embargo a la hora de hacerse un llamado a la función como 'h()' yo tengo entendido que realmente se crea un nuevo elemento en la pila que contiene informacion sobre la funcion 'h()' y ademas esa variable a la cual hago referencia mediante el apuntador global. El momento en donde entro en conflicto es cuando dices que la pila sigue ahi, te refieres a que una vez regresando al main la pila sigue ahi en el sentido de que la pila solo contiene la informacion relacionada con main o que ademas de seguir existiendo como primer elemento la informacion relacionada con 'main' se tiene que sigue existiendo todo lo relacionado con la funcion 'h()' que anteriormente fue llamada. El hecho de que sigan existiendo las dos funciones en las pila aun cuando ya se salio de la funcion 'h'[Mencionado que el puntero de la pila apunta a la funcion main] me hace dudar en el sentido de que:


1. Puedo interpretar que si se tiene muchas funciones en un programa lo mas seguro es que como mencionas que la pila se genera desde el comienzo y solo es eliminada hasta el final entonces yo tengo una pila con 'n' elementos que representan a cada funcion que posiblemente puede ser llamada desde mi funcion main.

2. En un programa donde se haga el llamado recursivo entonces el compilador deberia saber desde el comienzo del programa cuantos llamados a esa funcion se va realizar debido a que cada llamado a funcion debe tener distintos valores en sus variables y en dado caso rellenar la pila con informacion para cada uno de esos llamados lo que me lleva a que cuando termine de procesar todos los llamados a funciones no se va liberar/eliminar el elemento correspondiente a todas esas funciones en la pila.

3.Si no se libera entonces esta memoria que se vincula para cada llamado de funcion entonces yo podria estar seguro de que la zona de memoria que ocupo mi variable en alguna funcion no va poder ser modificada por una nueva demanda de memoria por parte del programa. En el caso de que realmente entonces si se vaya  liberando toda esa información vinculada a la funcion entonces caeria denuevo en cuenta de que es posible que realmente esa localidad en memoria que fue asignada para la variable 'a'  pueda ser modificada por alguien distinto al puntero, por ejemplo una asignación de memoria de una variable que fue utilizada en una función posterior.

Disculpame si soy algo terco, los casos anteriores solo son para la situación en la cual la pila sigue conservando todos los llamados a funciones aun cuando su llamado a finalizado que creo que es lo que he entendido  de tu anterior comentario.No descarto que tengas la razón pero en mi cabeza aún siguen sin encajar esas piezas. De nuevo te agradezco por tu tiempo.Todo lo anterior tambien lo digo por el hecho de que en los demas comentarios pareciera ser que la mayoria hagan inferencia de que no me puedo fiar de que la zona en donde apunta el apuntador  conserve el valor que yo asigne inicialmente en la funcion.
19  Programación / Programación General / Inicios de inteligencia artificial. en: 6 Marzo 2019, 06:22 am
Buenas a todos, quisiera saber si saben sobre algun curso/libro que de inicio al área de inteligencia artificial. Actualmente tengo conocimientos en materias como calculo integral/diferencial,algebra,logica matematica... etc y quisiera empezar a enfocar mis conocimientos en un área de mi interés antes de que empiece a olvidar algunas temas sobre ellas.

De antemano,gracias.
20  Programación / Programación C/C++ / Re: Preservacion del contenido de la memoria en contra de tiempo de vida de variable en: 5 Marzo 2019, 15:38 pm
Gracias a todos por su tiempo y comentarios, solo quisiera reafirmar si lo que pienso es correcto.
En el programa del inicio entonces tendria la siguiente situación.......
1. En la memoria 'stack' yo tendria inicialmente a la funcion main con todas su variables y en la memoria global tendria al puntero
2. Entra a la funcion 'h()' por lo cual en la memoria 'stack' se ve almacenada la informacion de la funcion y con ella la variable 'a'.( El proyecto dentro de una empresa empieza y me asigna una oficina ).
3. El puntero apunta a la dirección de memoria que tiene la variable 'a' . ( Tengo una llave que me ayuda a abrir la oficina ).
4. Termina la función 'h()' y por lo tanto se regresa a la funcion main con lo cual para el programa tanto las variables 'a' como el segmento de memoria que ella ocupaba ya no esta ocupado aun que yo tenga un puntero global apuntado anteriormente a ella ( El proyecto finaliza pero se me permite seguir conservando la llave ).
5. Finalmente se puede dar que con el puntero final yo pueda seguir accediendo a ese segmento de memoria y succeda algo de lo siguiente:
      -El segmento de memoria sigue conservando el valor que yo asigne a la variable 'a'.
      -El segmento de memoria contenga valores que el compilador asigno cuando se salio de la funcion para representar que esta vacio.
      -Que yo pueda seguir viendo el mismo valor de 'a' por gran parte del programa pero que pueda que tenga la mala suerte que ese segmento de memoria llegue a ser ocupado por el valor de una nueva variable y que al yo seguir haciendo referencia con el puntero global  no me puedo fiar en que ese segmento de memoria siga conteniendo el valor de 'a' que se le asigno inicialmente.


Finalmente entonces para asegurar que el puntero global pueda seguir conservando el valor 'a' sin problemas deberia hacer uso de una reservacion de memoria de manera dinamica con ayuda de new o malloc y asignarle el valor de la variable 'a'.
Páginas: 1 [2] 3
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines