MCPcopy
hub / github.com/tinygo-org/tinygo / tgs

Function tgs

diff.go:189–261  ·  view source on GitHub ↗

tgs returns the pairs of indexes of the longest common subsequence of unique lines in x and y, where a unique line is one that appears once in x and once in y. The longest common subsequence algorithm is as described in Thomas G. Szymanski, “A Special Case of the Maximal Common Subsequence Problem,

(x, y []string)

Source from the content-addressed store, hash-verified

187// Subsequence Problem,” Princeton TR #170 (January 1975),
188// available at https://research.swtch.com/tgs170.pdf.
189func tgs(x, y []string) []pair {
190 // Count the number of times each string appears in a and b.
191 // We only care about 0, 1, many, counted as 0, -1, -2
192 // for the x side and 0, -4, -8 for the y side.
193 // Using negative numbers now lets us distinguish positive line numbers later.
194 m := make(map[string]int)
195 for _, s := range x {
196 if c := m[s]; c > -2 {
197 m[s] = c - 1
198 }
199 }
200 for _, s := range y {
201 if c := m[s]; c > -8 {
202 m[s] = c - 4
203 }
204 }
205
206 // Now unique strings can be identified by m[s] = -1+-4.
207 //
208 // Gather the indexes of those strings in x and y, building:
209 // xi[i] = increasing indexes of unique strings in x.
210 // yi[i] = increasing indexes of unique strings in y.
211 // inv[i] = index j such that x[xi[i]] = y[yi[j]].
212 var xi, yi, inv []int
213 for i, s := range y {
214 if m[s] == -1+-4 {
215 m[s] = len(yi)
216 yi = append(yi, i)
217 }
218 }
219 for i, s := range x {
220 if j, ok := m[s]; ok && j >= 0 {
221 xi = append(xi, i)
222 inv = append(inv, j)
223 }
224 }
225
226 // Apply Algorithm A from Szymanski's paper.
227 // In those terms, A = J = inv and B = [0, n).
228 // We add sentinel pairs {0,0}, and {len(x),len(y)}
229 // to the returned sequence, to help the processing loop.
230 J := inv
231 n := len(xi)
232 T := make([]int, n)
233 L := make([]int, n)
234 for i := range T {
235 T[i] = n + 1
236 }
237 for i := 0; i < n; i++ {
238 k := sort.Search(n, func(k int) bool {
239 return T[k] >= J[i]
240 })
241 T[k] = J[i]
242 L[i] = k + 1
243 }
244 k := 0
245 for _, v := range L {
246 if k < v {

Callers 1

DiffFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected