Reputation: 2175
Given strings A and B, find all the occurrences of B in A as a subsequence.
Example:
A = "mañana de la mañana"
B = "mañana"
Answer:
0 -> mañana de la mañana
1 -> mañana de la mañana
2 -> mañana de la mañana
...
Based on an algorithm I found here which counts the number of occurrences there are 16 of those. I need an algorithm that finds all such subsequences and reports their indices.
Upvotes: 1
Views: 482
Reputation: 5703
The basic recursion be like
/**
* @param {[type]} iA current letter index in A
* @param {[type]} iB current letter index in B
*/
function rec (A, B, iA, iB, indices, solutions) {
if (iB === B.length) {
// copy the array if solution
solutions.push(indices.slice(0))
return
}
if (iA === A.length) {
return
}
const cb = B[iB]
// find all occurrences of cb in A
for (let i = iA; i < A.length; ++i) {
const ca = A[i]
if (ca === cb) {
indices[iB] = i
//match the next char
rec(A, B, i + 1, iB + 1, indices, solutions)
}
}
}
const A = "mañana de la mañana"
const B = "mañana"
const solutions = []
rec(A, B, 0, 0, [], solutions)
console.log(solutions.map(x => [
x.join(','), A.split('').map((c, i) => x.includes(i) ? c.toUpperCase() : c).join('')
]))
For the dynamic approach
m
and store them to S_m
a
from S_m
and store them to S_{ma}
const A = "mañana de la mañana"
const B = "mañana"
let S = A.split('').flatMap((a, i) => a === B[0] ? [[i]] : [])
// S is initially [ [0], [13] ]
B.split('').slice(1).forEach(b => {
const S_m = []
S.forEach(s => {
const iA = s[s.length - 1]
// get the last index from current sequence
// and look for next char in A starting from that index
for (let i = iA + 1; i < A.length; ++i) {
const ca = A[i]
if (ca === b) {
S_m.push(s.concat(i))
}
}
})
S = S_m
})
console.log(S.map(x => [
x.join(','), A.split('').map((c, i) => x.includes(i) ? c.toUpperCase() : c).join('')
]))
Upvotes: 1