如何在Swift中删除字符串中的重复字符

ruyhziif  于 2023-02-03  发布在  Swift
关注(0)|答案(6)|浏览(177)

ruby有string.squeeze函数,但我似乎找不到swift的等价函数。
例如,我想把簿记员-〉bokepr
我唯一的选择是创建一个字符集,然后将字符从集合中拉回到字符串吗?
有没有更好的办法?

xxls0lw8

xxls0lw81#

编辑/更新:* * Swift 4.2或更高版本**
可以使用集过滤重复字符:

let str = "bookkeeper"
var set = Set<Character>()
let squeezed = str.filter{ set.insert($0).inserted } 

print(squeezed)   //  "bokepr"

或者作为RangeReplaceableCollection上的扩展,也将扩展String和Substring:
x一个一个一个一个x一个一个二个x

sz81bmfz

sz81bmfz2#

我将使用another answer of mine中的这段代码,它删除序列的所有重复项(只保留每个重复项的第一次出现),同时保持顺序。

extension Sequence where Iterator.Element: Hashable {
    func unique() -> [Iterator.Element] {
        var alreadyAdded = Set<Iterator.Element>()
        return self.filter { alreadyAdded.insert($0).inserted }
    }
}

然后,我会用某种逻辑将它 Package 起来,将String转换成一个序列(通过获取它的characters),取消它,然后将结果恢复成一个字符串:

extension String {
    func uniqueCharacters() -> String {
        return String(self.characters.unique())
    }
}

print("bookkeeper".uniqueCharacters()) // => "bokepr"
ojsjcaue

ojsjcaue3#

这是我在网上找到的一个解决方案,但我不认为它是最佳的。

func removeDuplicateLetters(_ s: String) -> String {
    if s.characters.count == 0 {
        return ""
    }

    let aNum = Int("a".unicodeScalars.filter{$0.isASCII}.map{$0.value}.first!)
    let characters = Array(s.lowercased().characters)
    var counts = [Int](repeatElement(0, count: 26))
    var visited = [Bool](repeatElement(false, count: 26))
    var stack = [Character]()
    var i = 0

    for character in characters {
        if let num = asciiValueOfCharacter(character) {
            counts[num - aNum] += 1
        }
    }

    for character in characters {
        if let num = asciiValueOfCharacter(character) {
            i = num - aNum
            counts[i] -= 1
            if visited[i] {
                continue
            }
            while !stack.isEmpty, let peekNum = asciiValueOfCharacter(stack.last!), num < peekNum && counts[peekNum - aNum] != 0 {
                visited[peekNum - aNum] = false
                stack.removeLast()
            }
            stack.append(character)
            visited[i] = true
        }
    }

    return String(stack)
}

func asciiValueOfCharacter(_ character: Character) -> Int? {
    let value = String(character).unicodeScalars.filter{$0.isASCII}.first?.value ?? 0
    return Int(value)
}
pokxtpni

pokxtpni4#

下面是使用reduce()执行此操作的一种方法,

let newChar = str.characters.reduce("") { partial, char in
  guard let _ = partial.range(of: String(char)) else {
    return partial.appending(String(char))
  }
  return partial
}

正如Leo所建议的,这里是同一方法的一个简短版本,

let newChar = str.characters.reduce("") { $0.range(of: String($1)) == nil ? $0.appending(String($1)) : $0 }
pes8fvy9

pes8fvy95#

只是另一种解决方案

let str = "Bookeeper"
let newChar = str.reduce("" , {
    if $0.contains($1) {
        return "\($0)"
    } else {
      return "\($0)\($1)"
    }
})

print(str.replacingOccurrences(of: " ", with: ""))
6tdlim6h

6tdlim6h6#

使用筛选器和包含删除重复值

let str = "bookkeeper"
let result = str.filter{!result.contains($0)}
print(result) //bokepr

相关问题