Самая длинная общая подпоследовательность между двумя строками может быть рекурсивно определена следующим образом:
func lcs(_ str1: String, _ str2: String, _ i: String.Index, _ j: String.Index) -> Int
{
if (i == str1.startIndex || j == str2.startIndex) {
return 0
}
let beforeI = str1.index(before: i)
let beforeJ = str2.index(before: j)
if str1[beforeI] == str2[beforeJ] {
return 1 + lcs(str1, str2, beforeI, beforeJ)
} else {
return max(lcs(str1, str2, i, beforeJ), lcs(str1, str2, beforeI, j))
}
}
Вы можете найти полное объяснение того, как работает этот алгоритм динамического программирования здесь .
Итак, учитывая массив строк и текст для поиска:
let array = ["ram", "gopal", "varma", "govind", "ravan", "alan", "logan"]
let searchText = "goal"
Мы можем связать оценку с каждым элементом массива, отфильтровать только те, которые имеют ненулевую оценку, отсортировать их понабрать, а затем набрать только слова из кортежей:
let result = array
.map { ($0, lcs(searchText,
$0,
searchText.endIndex,
$0.endIndex)) }
.filter { $0.1 > 0 }
.sorted { $0.1 > $1.1 }
.map { $0.0 }
print(result)
Что дает:
["gopal", "govind", "alan", "logan", "ram", "varma", "ravan"]