¿Cómo encontrar la subcadena común más larga usando árboles?

El problema de subcadena común más largo según wiki se puede resolver usando un árbol de sufijos.
Desde wiki:

Las subcadenas comunes más largas de un conjunto de cadenas se pueden encontrar construyendo un árbol de sufijos generalizado para las cadenas y luego encontrando los nodos internos más profundos que tienen nodos de hoja de todas las cadenas en el subárbol debajo de él.

No entiendo esto.
Ejemplo: si tengo:
ABCDE y XABCZ
entonces el árbol de sufijos es (algunas ramas de XABCZ omitido por espacio):
enter image description here

La subcadena común más larga es ABC pero no es así. No puedo ver cómo la descripción de wiki ayuda aquí.
ABC no es los nodos internos más profundos con nodos de hoja.
¿Alguna ayuda para entender cómo funciona esto?

preguntado el 12 de junio de 12 a las 21:06

ABC is not the deepest internal nodes with leaf nodes. No, pero ABC is el mas largo común cadena de nodos en cualquier parte del árbol. Los siguientes más largos son B-C y D-E, con dos nodos cada uno. -

ABC es la cadena común más larga. Pero no entiendo cómo la descripción de la wiki realmente me ayudaría a encontrarlo programáticamente:

Tienes que leer la otra Wiki: en.wikipedia.org/wiki/Generalised_suffix_tree. Probablemente haya algunos recursos mejores (más fácilmente comprensibles) aquí. Ver también stackoverflow.com/questions/969448/… -

@ user384706: creo que parte del problema es que no es un árbol de sufijos adecuado. Deberías solo una rama que empiece por raíz-ABC, y la C tendría dos hijos: DE y Z. Similar para el resto de las ramas. Lo que tienes allí es básicamente una lista de sufijos que tienen un nodo raíz que los señala. -

@twalberg: Sí, tienes razón. Las 2 ramas azules serían una. Pero en este caso, ¿cómo podría encontrarlos programáticamente? No me queda claro cómo ayuda la descripción de la wiki:

2 Respuestas

Como se ha dicho antes, su árbol es incorrecto.

Esto es lo que obtengo cuando ejecuto "ABCDE$XABCZ" a través de mi código.

Código de árbol de sufijos:

String = ABCDE$XABCZ$
End of word character 1 = $
└── (0)
    ├── (20) $
    ├── (22) ABC
    │   ├── (15) DE$
    │   └── (23) Z$
    ├── (24) BC
    │   ├── (16) DE$
    │   └── (25) Z$
    ├── (26) C
    │   ├── (17) DE$
    │   └── (27) Z$
    ├── (18) DE$
    ├── (19) E$
    ├── (21) XABCZ$
    └── (28) Z$

En un árbol de sufijos (compacto), debe encontrar los nodos internos más profundos que tengan nodos de hoja de todas las cadenas. Si tiene varios nodos a la misma profundidad, debe comparar la longitud de la cadena representada por ese nodo. es decir, ABC, BC y C tienen la misma profundidad, por lo que debe comparar la longitud de las cuerdas ABC, BC y C para ver cuál es más larga; que es ABC obviamente.

Código de sufijo Trie:

└── null
    ├── A
    │   └── B
    │       └── C
    │           ├── D
    │           │   └── (E) ABCDE
    │           └── (Z) ABCZ
    ├── B
    │   └── C
    │       ├── D
    │       │   └── (E) BCDE
    │       └── (Z) BCZ
    ├── C
    │   ├── D
    │   │   └── (E) CDE
    │   └── (Z) CZ
    ├── D
    │   └── (E) DE
    ├── (E) E
    ├── X
    │   └── A
    │       └── B
    │           └── C
    │               └── (Z) XABCZ
    └── (Z) Z

En un trie de sufijo (no compacto), busque los nodos internos más profundos que tengan nodos de hoja de todas las cadenas.

Espero eso ayude.

Respondido el 08 de diciembre de 15 a las 16:12

¿Es este un árbol de sufijos "colapsado"? También cuáles son los números, por ejemplo (20) or (24) ¿etc? - Cratilo

Sí, esto está colapsado, pero colapsar significa fusionar, por ejemplo, "DE" en un solo nodo. Sin embargo, todos los árboles de sufijos combinarían "CDE$" y "CZ$" en un nodo "C" con una rama "DE$" y una rama "Z$", pero un árbol de sufijos colapsado trataría "DE$". como un nodo, y un árbol de sufijos no colapsado trataría "DE$" como tres nodos, uno para cada carácter. - Luis Wassermann

@ user384706 Sí, es un árbol colapsado. Los números son solo identificadores de nodos, nada a tener en cuenta. También he creado un sufijo trie, si está interesado. Lo agregué a la respuesta. - Justin

En realidad no has dibujado el árbol de sufijos. Si lo hubiera hecho correctamente, en la raíz solo tendría todos los caracteres posibles una vez. El árbol solo se divide cuando una sola letra puede tener varios sufijos siguientes. Eso fuerza las subcadenas comunes juntas en el árbol, lo que las hace encontrables.

Respondido el 12 de junio de 12 a las 21:06

No estoy seguro de seguirte aquí. Si la cadena fuera: ABCDBEF entonces habría una subrama debajo B para BCDBEF y BEF pero para este ejemplo, es decir ABCDE ¿No tendremos una rama para cada posible sufijo? - Cratilo

En el diagrama de ejemplo que diste, debe haber como máximo un hijo de la raíz etiquetado como 'A'. Deberías haber fusionado esos dos nodos. - Luis Wassermann

@LouisWasserman: ¿En serio? ¿Por qué?A es un prefijo en ABCDE. ¿Por qué habría un nodo secundario de raíz que es A? - Cratilo

El objetivo de un árbol de sufijos es fusionar prefijos coincidentes de sufijos en las mismas raíces. Debería haber una rama de la raíz que vaya ABC, y luego ese último nodo debería tener dos hijos, uno X y uno DE. - Luis Wassermann

@LouisWasserman: Bueno. Estoy de acuerdo. Pero en este caso, es decir, tener los 2 nodos combinados, ¿cómo puedo encontrar mediante programación la subcadena común más larga usando la descripción de wiki? Estoy atascado en esto: Cratilo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.