基于多个字符串分隔符分割字符串的高效算法

时间:2021-02-07 22:04:43

标签: swift string algorithm

我想知道是否有一种有效的方法可以根据也是字符串的分隔符将字符串拆分为多个字符串。 例如。 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%")

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

更清楚地说,我不仅想要字符,还想要字符串作为分隔符:

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

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

3 个答案:

答案 0 :(得分:5)

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

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

这是有效的,因为集合上的 contains 非常快,所以成本可以忽略不计,我们只隐式地循环一次原始字符串。

另一方面,您可以利用 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)

答案 1 :(得分:2)

其中一个 components(separatedBy:) 重载将使用 CharacterSet 自动处理:

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

答案 2 :(得分:0)

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
}
相关问题