【问题标题】:Find most common substring from an Array of Strings从字符串数组中查找最常见的子字符串
【发布时间】:2019-07-16 05:52:43
【问题描述】:

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

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

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

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

即在gopalgoal 中只有p 缺失,因此它应该在具有更高优先级的搜索列表中。

有没有办法进行这种过滤?

【问题讨论】:

  • 你需要单个对象还是多个对象?
  • 实际上我想要一个项目数组,如问题所示。即包含搜索文本子序列的所有项目。但最相似的单词应该在列表中显示为第一个。
  • "ram" 等中有一个a。公共子序列是否应该至少有 2 个字符?
  • array = ["ram","gopal","varma","govind","varma","ravan","gopal","ravan","alan"] 会是什么输出?请分享这个数组。
  • @Carpsen90 是的,这是真的。我使用上面的结果只是为了显示我的优先级。 varma、ram、ravan 也应该在列表中,因为它们有一个共同点。结果 = [“gopal”、“govind”、“alan”、“varma”、“ravan”、“ram”]

标签: ios arrays swift search longest-substring


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您想找到最长的公共子序列。我建议您查看 this Ray Wenderlich 的 Swift Algorithm Club 上的优秀文章,在那里您可以通过示例找到您的解决方案。

    编辑:

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

    例如这样:

    let array = ["ram", "gopal", "varma", "govind", "ravan", "alan"]
    let searchTerm = "goal"
    
    var dictionary: [String: Int] = [:]
    for element in array {
        dictionary[element] = searchTerm.longestCommonSubsequence(element).count
    }
    
    let result = dictionary.sorted(by: { $0.1 > $1.1 }).map { $0.key }
    

    【讨论】:

    • 是的。我可以找到最长的公共子序列算法。但这用于比较2个字符串对吗?我有一个包含 1000 个项目的数组,因为这很难做到。
    • 您必须遍历您的数组并跟踪每个世界的子序列有多长(例如在字典中)。然后你必须按子序列长度对数组进行排序。
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 2011-02-03
    • 2020-02-23
    • 2012-12-08
    • 2021-12-28
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多