【问题标题】:Efficient algorithm to split a string based on multiple string delimiters基于多个字符串分隔符拆分字符串的高效算法
【发布时间】:2021-02-07 22:04:43
【问题描述】:

我想知道是否有一种有效的方法可以根据也是字符串的分隔符将字符串拆分为多个字符串。 例如。 updateStr = "23+45 = 56 0" ,分隔符 = ["+"," ","="]

结果 = [23,45,56,0]

我在swift中尝试了以下代码:

for i in 0..<delimiter.count {
    let res = updateStr.components(separatedBy: delimiter[i])
    updateStr = res.joined(separator: "unique%")
 }
splitTxt = updateStr.components(separatedBy: "unique%")

这可行,但由于分隔符将被动态接收,我想要一个更好的方法。 有没有有效的方法来避免多个循环来解决这个问题? 具有更有效解决方案且不涉及快速实例方法的算法也将受到赞赏。 感谢您的回答,但是

为了更清楚,我不只是想要字符而是字符串作为分隔符:

例如2。 updateStr = "我喜欢和朋友一起玩" , delimiters = ["li"," "la","ie"]

结果 = ["I","ke p","ying with fr","nds"]

【问题讨论】:

    标签: swift string algorithm


    【解决方案1】:

    做这种事情的有效方法是使用 Set:

    let equation = "23+45 = 56 0"
    let delimiters : [Character] = ["+"," ","="]
    let setOfSeparators = Set(delimiters)
    let result = equation.split {setOfSeparators.contains($0)}
    print(result)
    

    这很有效,因为 contains 在 Set 上的速度非常快,因此成本可以忽略不计,而且我们只在原始字符串中隐式循环一次。

    另一方面,您可以利用 Cocoa CharacterSet 类。为此,我想说:

    let equation = "23+45 = 56 0"
    let delimiters = ["+"," ","="]
    let characterSet = CharacterSet(charactersIn: delimiters.joined())
    let result = equation.components(separatedBy: characterSet).filter {!$0.isEmpty}
    print(result)
    

    另一种有趣的方法是使用扫描仪(我认为这些都没有得到充分利用):

    let equation = "23+45 = 56 0"
    let delimiters = ["+"," ","="]
    let characterSet = CharacterSet(charactersIn: delimiters.joined())
    let scanner = Scanner(string: equation)
    var result = [String]()
    while let word = scanner.scanUpToCharacters(from: characterSet) {
        result.append(word)
        scanner.scanCharacters(from: characterSet)
    }
    print(result)
    

    【讨论】:

    • 感谢您的回答,但如前所述,我也希望它用于字符串。我已编辑问题以包含相同的示例
    • 多么美丽的答案
    • 这不会改变我回答的第一部分,是吗?
    【解决方案2】:

    components(separatedBy:) 重载之一将使用 CharacterSet 自动处理此问题:

    let delimiters = ["+"," ","="].compactMap(UnicodeScalar.init)
    let splitTxt = updateStr.components(separatedBy: CharacterSet(delimiters))
    

    【讨论】:

    • 对不起,不是故意的。
    • @matt 你的可能实际上在第一次尝试时就起作用了:D(我不得不把它弄乱几次才能让它正确)
    • 我添加了使用 Scanner 来挖掘,所以它看起来不像你的那么像。 :)
    • 总是加倍努力。
    • @LeoDabus 是的,它需要与马特在他的答案中添加的最后相同的 .filter {!$0.isEmpty}
    【解决方案3】:

    NSRegularExpression 提供了对一般正则表达式进行拆分的工具,因此这将允许使用 delim1|delim2|delim3 正则表达式在有限的字符串定界符集上进行拆分。以下拆分操作完成了这项工作:

    static func stringSubrange(str : String, st : Int, en : Int) -> String
    { var result : [Character] = [Character]()
      var count : Int = 0
    
      for index in str.indices
      { let c : Character = str[index]
        count = count + 1
        if count >= st && count <= en
        { result.append(c) }
        else if count > en
        { return String(result) }
      }
      return String(result)
    }
    
    
    static func split(str: String, pattern: String) -> [String]
    { let rge = NSRange(location: 0, length: str.utf16.count)
      let regexp = try! NSRegularExpression(pattern: pattern)
      let pred = regexp.matches(in: str, options: [], range: rge)
      var result : [String] = [String]()
      var prev : Int = 1; 
    
      for p in pred
      { let range = p.range
        let splitString = Ocl.stringSubrange(str: str, st: prev, en: range.location)
        prev = range.location + range.length + 1
        if splitString.count > 0
        { result.append(splitString) }
      }
    
      if prev < str.count
      { result.append(Ocl.stringSubrange(str: str, st: prev, en: str.count)) } 
      return result
    }
    

    【讨论】:

      猜你喜欢
      • 2011-11-28
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-13
      • 2023-03-08
      相关资源
      最近更新 更多