@Override public int hashCode() { int result = 17; switch (tipo) { case CIERRE: result = result * 31; break; case CONCAT: result = result * 31 + 1; break; case SIMBOLO: result = result * 31 + 2; break; case UNION: result = result * 31 + 3; break; case VACIO: result = result * 31 + 4; break; } // result = result * 31 + posicion; result = result * 31 + simbolo; result = result * 31 + (hijoIzquierdo != null ? hijoIzquierdo.hashCode() : 0); result = result * 31 + (hijoDerecho != null ? hijoDerecho.hashCode() : 0); return result; }
/** * Devuelve la lista de nodos que constituyen la expresión. * * @return Nodos que forman la expresión. */ public List<ExpresionRegular> nodos() { List<ExpresionRegular> nodos = new ArrayList<>(); Stack<ExpresionRegular> pila = new Stack<>(); pila.add(this); ExpresionRegular actual = this; while (!pila.isEmpty()) { nodos.add(actual); if (!actual.esSimbolo() && !actual.esVacio()) { pila.push(actual.hijoIzquierdo()); if (!actual.esCierre()) pila.push(actual.hijoDerecho()); } actual = pila.pop(); } return nodos; }
/** * Dibuja el árbol de la expresión regular como grafo. * * @return Imagen representando el árbol de la expresión regular. */ public BufferedImage imagen() { if (this.imagen == null) { mxGraph graph = new mxGraph(); Object parent = graph.getDefaultParent(); Map<ExpresionRegular, Object> gNodos = new HashMap<>(); ExpresionRegular actual; Object gNodo, gActual; List<ExpresionRegular> siguientes = new ArrayList<>(); boolean tieneHijoIzquierdo, tieneHijoDerecho; String estiloVertex = "shape=ellipse;fillColor=white;strokeColor=black;fontColor=black;"; String estiloEdge = "strokeColor=black;fontColor=black;labelBackgroundColor=white;endArrow=open;"; graph.getModel().beginUpdate(); try { siguientes.add(this); while (!siguientes.isEmpty()) { actual = siguientes.get(0); if (!gNodos.containsKey(actual)) { gActual = graph.insertVertex(parent, null, actual.tipo(), 0, 0, 30, 30, estiloVertex); gNodos.put(actual, gActual); } else { gActual = gNodos.get(actual); } tieneHijoIzquierdo = !actual.esSimbolo() && !actual.esVacio(); tieneHijoDerecho = tieneHijoIzquierdo && !actual.esCierre(); if (tieneHijoIzquierdo) { siguientes.add(actual.hijoIzquierdo()); gNodo = graph.insertVertex( parent, null, actual.hijoIzquierdo().tipo(), 0, 0, 30, 30, estiloVertex); graph.insertEdge(parent, null, "", gActual, gNodo, estiloEdge); gNodos.put(actual.hijoIzquierdo(), gNodo); } if (tieneHijoDerecho) { siguientes.add(actual.hijoDerecho()); gNodo = graph.insertVertex( parent, null, actual.hijoDerecho().tipo(), 0, 0, 30, 30, estiloVertex); graph.insertEdge(parent, null, "", gActual, gNodo, estiloEdge); gNodos.put(actual.hijoDerecho(), gNodo); } siguientes.remove(actual); } } finally { graph.getModel().endUpdate(); mxGraphComponent graphComponent = new mxGraphComponent(graph); new mxHierarchicalLayout(graph, SwingConstants.NORTH).execute(parent); new mxParallelEdgeLayout(graph).execute(parent); this.imagen = mxCellRenderer.createBufferedImage( graph, null, 1, Color.WHITE, graphComponent.isAntiAlias(), null, graphComponent.getCanvas()); } } return this.imagen; }