从字符串数组中查找最常见的子字符串

时间:2019-02-22 07:19:04

标签: ios arrays swift search longest-substring

我想从字符串数组中搜索一个单词。

array = ["ram","gopal","varma","govind","ravan","alan"]

如果我的搜索文字是goal,我想列出如下:

result = ["gopal","govind","alan"]

即在gopalgoal中仅缺少p,因此它应该在优先级更高的搜索列表中。

有什么办法可以进行这种过滤吗?

2 个答案:

答案 0 :(得分:0)

您想找到最长的公共子序列。我建议您阅读Ray Wenderlich的Swift算法俱乐部上的this优秀文章,在其中可以找到带有示例的解决方案。

编辑:

然后,您必须遍历数组,并跟踪每个世界的子序列有多长时间(例如在词典中)。然后,您必须按照子序列的长度对数组进行排序。

例如这样的例子:

.portlet-fullscreen {
    display: block;
    position: absolute;
    width: 80%;
    left: 0;
}

答案 1 :(得分:0)

两个字符串之间最长的公共子序列可以如下递归定义:

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))
    }
}

您可以here找到有关此动态编程算法如何工作的完整说明。

因此,给定一个字符串数组和一个搜索文本:

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"]