|
| 1 | +# Suffix Array Construction |
| 2 | + |
| 3 | +## English |
| 4 | + |
| 5 | +The suffix array is a powerful data structure used in string processing to enable efficient pattern searches and substring queries. This challenge involves constructing the suffix array and the LCP (Longest Common Prefix) array for a given string. |
| 6 | + |
| 7 | +The suffix array is built by sorting all suffixes of the string. The LCP array stores the length of the longest common prefix between consecutive suffixes in the suffix array, which helps speed up pattern matching and other string processing tasks. |
| 8 | + |
| 9 | +### Relevant Code Snippet |
| 10 | + |
| 11 | +```javascript |
| 12 | +class SuffixArray { |
| 13 | + constructor(text) { |
| 14 | + this.text = text; |
| 15 | + this.n = text.length; |
| 16 | + this.suffixArray = []; |
| 17 | + this.lcpArray = []; |
| 18 | + } |
| 19 | + |
| 20 | + buildSuffixArray() { |
| 21 | + this.suffixArray = Array.from({ length: this.n }, (_, i) => i); |
| 22 | + this.suffixArray.sort((a, b) => { |
| 23 | + const substrA = this.text.substring(a); |
| 24 | + const substrB = this.text.substring(b); |
| 25 | + if (substrA < substrB) return -1; |
| 26 | + if (substrA > substrB) return 1; |
| 27 | + return 0; |
| 28 | + }); |
| 29 | + return this.suffixArray; |
| 30 | + } |
| 31 | + |
| 32 | + buildLCPArray() { |
| 33 | + if (this.suffixArray.length === 0) { |
| 34 | + this.buildSuffixArray(); |
| 35 | + } |
| 36 | + |
| 37 | + this.lcpArray = new Array(this.n).fill(0); |
| 38 | + const invSuffix = new Array(this.n); |
| 39 | + |
| 40 | + for (let i = 0; i < this.n; i++) { |
| 41 | + invSuffix[this.suffixArray[i]] = i; |
| 42 | + } |
| 43 | + |
| 44 | + let k = 0; |
| 45 | + for (let i = 0; i < this.n; i++) { |
| 46 | + if (invSuffix[i] === this.n - 1) { |
| 47 | + k = 0; |
| 48 | + continue; |
| 49 | + } |
| 50 | + const j = this.suffixArray[invSuffix[i] + 1]; |
| 51 | + while (i + k < this.n && j + k < this.n && this.text[i + k] === this.text[j + k]) { |
| 52 | + k++; |
| 53 | + } |
| 54 | + this.lcpArray[invSuffix[i]] = k; |
| 55 | + if (k > 0) k--; |
| 56 | + } |
| 57 | + |
| 58 | + return this.lcpArray; |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +### History |
| 64 | + |
| 65 | +Suffix arrays and LCP arrays are fundamental data structures in string processing, enabling efficient pattern matching, substring queries, and bioinformatics applications. They are a space-efficient alternative to suffix trees. |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## Español |
| 70 | + |
| 71 | +El arreglo de sufijos es una estructura de datos poderosa utilizada en el procesamiento de cadenas para permitir búsquedas eficientes de patrones y consultas de subcadenas. Este reto consiste en construir el arreglo de sufijos y el arreglo LCP (Longest Common Prefix) para una cadena dada. |
| 72 | + |
| 73 | +El arreglo de sufijos se construye ordenando todos los sufijos de la cadena. El arreglo LCP almacena la longitud del prefijo común más largo entre sufijos consecutivos en el arreglo de sufijos, lo que ayuda a acelerar la búsqueda de patrones y otras tareas de procesamiento de cadenas. |
| 74 | + |
| 75 | +### Fragmento de Código Relevante |
| 76 | + |
| 77 | +```javascript |
| 78 | +class SuffixArray { |
| 79 | + constructor(text) { |
| 80 | + this.text = text; |
| 81 | + this.n = text.length; |
| 82 | + this.suffixArray = []; |
| 83 | + this.lcpArray = []; |
| 84 | + } |
| 85 | + |
| 86 | + buildSuffixArray() { |
| 87 | + this.suffixArray = Array.from({ length: this.n }, (_, i) => i); |
| 88 | + this.suffixArray.sort((a, b) => { |
| 89 | + const substrA = this.text.substring(a); |
| 90 | + const substrB = this.text.substring(b); |
| 91 | + if (substrA < substrB) return -1; |
| 92 | + if (substrA > substrB) return 1; |
| 93 | + return 0; |
| 94 | + }); |
| 95 | + return this.suffixArray; |
| 96 | + } |
| 97 | + |
| 98 | + buildLCPArray() { |
| 99 | + if (this.suffixArray.length === 0) { |
| 100 | + this.buildSuffixArray(); |
| 101 | + } |
| 102 | + |
| 103 | + this.lcpArray = new Array(this.n).fill(0); |
| 104 | + const invSuffix = new Array(this.n); |
| 105 | + |
| 106 | + for (let i = 0; i < this.n; i++) { |
| 107 | + invSuffix[this.suffixArray[i]] = i; |
| 108 | + } |
| 109 | + |
| 110 | + let k = 0; |
| 111 | + for (let i = 0; i < this.n; i++) { |
| 112 | + if (invSuffix[i] === this.n - 1) { |
| 113 | + k = 0; |
| 114 | + continue; |
| 115 | + } |
| 116 | + const j = this.suffixArray[invSuffix[i] + 1]; |
| 117 | + while (i + k < this.n && j + k < this.n && this.text[i + k] === this.text[j + k]) { |
| 118 | + k++; |
| 119 | + } |
| 120 | + this.lcpArray[invSuffix[i]] = k; |
| 121 | + if (k > 0) k--; |
| 122 | + } |
| 123 | + |
| 124 | + return this.lcpArray; |
| 125 | + } |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +### Historia |
| 130 | + |
| 131 | +Los arreglos de sufijos y los arreglos LCP son estructuras de datos fundamentales en el procesamiento de cadenas, que permiten búsquedas eficientes de patrones, consultas de subcadenas y aplicaciones en bioinformática. Son una alternativa eficiente en espacio a los árboles de sufijos. |
0 commit comments