【问题标题】:Find the repeated sequence in the line that go in a row在一行中找到重复的序列
【发布时间】:2019-08-06 10:07:55
【问题描述】:

给定一个任意长度的字符串。我需要找到 1 个连续的相同字符的子序列。

我的函数(其中有两个,但它们是同一个函数的两个部分)结果变得复杂而繁琐,因此不适合。我需要的函数应该很简单,不要太长。

示例:

Input : str = "abcabc"
Output : abc

Input : str = "aa"
Output : a

Input : str = "abcbabcb"
Output : abcb

Input : str = "abcbca"
Output : bcbc

Input : str = "cbabc"
Output : 

Input : str = "acbabc"
Output :

我不成功的功能:

func findRepetition(_ p: String) -> [String:Int] {
    var repDict: [String:Int] = [:]
    var p = p
    while p.count != 0 {
        for i in 0...p.count-1 {
            repDict[String(Array(p)[0..<i]), default: 0] += 1
        }
        p = String(p.dropFirst())
    }
    return repDict
}

var correctWords = [String]()
var wrongWords = [String]()
func getRepeats(_ p: String) -> Bool {
    let p = p
    var a = findRepetition(p)
    for i in a {
        var substring = String(Array(repeating: i.key, count: 2).joined())
        if p.contains(substring) {
            wrongWords.append(p)
            return false
        }
    }
    correctWords.append(p)
    return true
}

非常感谢您的帮助!

【问题讨论】:

  • 在第四个例子“abcbca”中,输出不应该是“bc”吗?

标签: swift function subsequence


【解决方案1】:

这是一个使用正则表达式的解决方案。我使用了一个捕获组,它尝试匹配尽可能多的字符,以便整个组至少重复一次。

import Foundation

func findRepetition(_ s: String) -> String? {
    if s.isEmpty { return nil }
    let pattern = "([a-z]+)\\1+"
    let regex = try? NSRegularExpression(pattern: pattern, options: [])
    if let match = regex?.firstMatch(in: s, options: [], range: 
NSRange(location: 0, length: s.utf16.count)) {
        let unitRange = match.range(at: 1)
        return (s as NSString).substring(with: unitRange)
    }
    return nil
}

print(findRepetition("abcabc")) //prints abc
print(findRepetition("aa")) //prints a
print(findRepetition("abcbabcb")) //prints abcb
print(findRepetition("abcbca")) //prints bc
print(findRepetition("cbabc")) //prints nil
print(findRepetition("acbabc")) //prints nil

【讨论】:

    【解决方案2】:
    func findRepetitions(_ p : String) -> [String: Int]{
        let half = p.count / 2 + 1
        var result : [String : Int] = [:]
        for i in 1..<half {
            for j in 0...(p.count-i) {
                let sub = (p as! NSString).substring(with: NSRange.init(location: j, length: i))
                if let val = result[sub] {
                    result[sub] = val + 1
                }else {
                    result[sub] = 1
                }
            }
        }
        return result
    }
    

    这是为了在你的字符串中寻找可能的子字符串的重复。希望对你有帮助

    【讨论】:

    • 您好,感谢您的反馈。在 abcabc 行的情况下,我得到 ["bc": 2, "abc": 2, "a": 2, "bca": 1, "cab": 1, "ab": 2, "ca" : 1, "c": 2, "b": 2],但我如何理解其中哪一个是连续出现的? (在我的例子中,函数应该只返回“abc”)
    • 最长重复次数最多的子串是你的需要
    • 在字符串“abcabc”的示例中,函数返回“bc”、“abc”、“a” = 2。
    • "abc" 是最长的 :)
    • omg,那个字典已经给你重复了,你可以根据这些计数来检测哪个有2个相同的子序列@@
    【解决方案3】:

    这是一个基于Suffix Array Algorithm 的解决方案,它找到重复(连续)的最长子字符串:

    func longestRepeatedSubstring(_ str: String) -> String {
    
        let sortedSuffixIndices = str.indices.sorted { str[$0...] < str[$1...] }
        let lcsArray = [0]
            +
            sortedSuffixIndices.indices.dropFirst().map { index in
                let suffix1 = str[sortedSuffixIndices[index]...]
                let suffix2 = str[sortedSuffixIndices[index - 1]...]
                let commonPrefix = suffix1.commonPrefix(with: suffix2)
                let count = commonPrefix.count
                let repeated = suffix1.dropFirst(count).commonPrefix(with: commonPrefix)
                return count == repeated.count ? count : 0
        }
    
        let maxRepeated = zip(sortedSuffixIndices.indices,lcsArray).max(by: { $0.1 < $1.1 })
    
        if let tuple = maxRepeated, tuple.1 != 0 {
            let suffix1 = str[sortedSuffixIndices[tuple.0 - 1]...]
            let suffix2 = str[sortedSuffixIndices[tuple.0]...]
            let longestRepeatedSubstring = suffix1.commonPrefix(with: suffix2)
            return longestRepeatedSubstring
        } else {
            return ""
        }
    }
    

    Here 是关于此类算法的易于理解的教程。

    适用于以下示例:

    longestRepeatedSubstring("abcabc")    //"abc"
    longestRepeatedSubstring("aa")        //"a"
    longestRepeatedSubstring("abcbabcb")  //"abcd"
    longestRepeatedSubstring("abcbca")    //"bcbc"
    longestRepeatedSubstring("cbabc")     //""
    longestRepeatedSubstring("acbabc")    //""
    

    还有这些:

    longestRepeatedSubstring("a?ca?c")    //"a?c"
    longestRepeatedSubstring("Ab cdAb cd")  //"Ab cd"
    longestRepeatedSubstring("aabcbc")      //"bc"
    

    基准测试

    Here 是一个基准,它清楚地表明 Suffix Array 算法比使用正则表达式要快得多。

    结果是:

    Regular expression: 7.2 ms
    Suffix Array      : 0.1 ms
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多