Ios 方法,该方法删除字符串中所有两次重复的字符

Ios 方法,该方法删除字符串中所有两次重复的字符,ios,swift,string,character,Ios,Swift,String,Character,我编写了一个删除字符串中所有2个重复字符的方法,例如 我只需要删除包含两次的字符,例如 “bndkss”->“bndk” “nnmmhj”->“hj” “aaabbaac”->“ac “abba”->” 我在objc上写过,一切正常,但Swift不工作,请帮帮我,我哪里出错了 override func viewDidLoad() { super.viewDidLoad() let string = "baab" print("before: \(string)")

我编写了一个删除字符串中所有2个重复字符的方法,例如
我只需要删除包含两次的字符,例如
“bndkss”->“bndk”
“nnmmhj”->“hj”
“aaabbaac”->“ac
“abba”->”

我在objc上写过,一切正常,但Swift不工作,请帮帮我,我哪里出错了

override func viewDidLoad() {
    super.viewDidLoad()

    let string = "baab"
    print("before: \(string)")
    let stringAfter = checkString(string: string)
    print("after: \(stringAfter)")
}

func checkString(string : String) -> String {
    var tempString = string
    for (index, element) in string.characters.enumerated() {

        for (index2, element2) in string.characters.enumerated() {
            if element == element2 && index != index2 {
                if index > index2 {
                    tempString.remove(at: tempString.index(tempString.startIndex, offsetBy: index))
                    tempString.remove(at: tempString.index(tempString.startIndex, offsetBy: index2))
                } else {
                    tempString.remove(at: tempString.index(tempString.startIndex, offsetBy: index2))
                    tempString.remove(at: tempString.index(tempString.startIndex, offsetBy: index))
                }

                if tempString.characters.count < 1 {
                    return ""
                } else {
                    checkString(string: tempString)
                }
            } else {
                if index == tempString.characters.count - 1 && index2 == tempString.characters.count - 1 {
                    return tempString
                }
            }
        }
    }

    return ""
}
反而

checkString(string: tempString)

代码中有两个问题,例如

  • 删除
    tempString
    中的字符后,要长时间引用
    tempString
    中原始字符的索引
    index
    index2
    。 因此,会删除错误的字符
  • 递归调用
    checkString()
    ,但放弃结果
更新:正如您已经注意到的,
返回checkString(string:tempString)
解决了这些问题

这里有一个替代的实现,其思想是使用字典 记住最后一次看到字符的位置和索引集 它跟踪要删除的字符的位置 被保留。两个“简单”取代了两个嵌套循环和递归 这里使用循环,加上字典和集合操作的成本

func removeDuplicateCharacters(string: String) -> String {

    var seen = [Character: Int]()
    var keep = IndexSet(integersIn: 0..<string.characters.count)

    for (idx, c) in string.characters.enumerated() {
        if let prevIndex = seen[c] {
            keep.remove(prevIndex)
            keep.remove(idx)
            seen.removeValue(forKey: c)
        } else {
            seen[c] = idx
        }
    }
    return String(keep.map { string[string.index(string.startIndex, offsetBy: $0)] })
}

代码中有两个问题,例如

  • 删除
    tempString
    中的字符后,要长时间引用
    tempString
    中原始字符的索引
    index
    index2
    。 因此,会删除错误的字符
  • 递归调用
    checkString()
    ,但放弃结果
更新:正如您已经注意到的,
返回checkString(string:tempString)
解决了这些问题

这里有一个替代的实现,其思想是使用字典 记住最后一次看到字符的位置和索引集 它跟踪要删除的字符的位置 被保留。两个“简单”取代了两个嵌套循环和递归 这里使用循环,加上字典和集合操作的成本

func removeDuplicateCharacters(string: String) -> String {

    var seen = [Character: Int]()
    var keep = IndexSet(integersIn: 0..<string.characters.count)

    for (idx, c) in string.characters.enumerated() {
        if let prevIndex = seen[c] {
            keep.remove(prevIndex)
            keep.remove(idx)
            seen.removeValue(forKey: c)
        } else {
            seen[c] = idx
        }
    }
    return String(keep.map { string[string.index(string.startIndex, offsetBy: $0)] })
}

马丁写了一个比我干净得多的版本,但我在这方面做了一段时间,所以我想我会把它贴出来,向你展示实现它的另一种方式

func removeDuplicates(from original: String) -> String {
var originalString = original
var newString = ""

for character in originalString.characters {
if !newString.contains("\(character)") {
    newString.append(character)
     originalString = originalString.characters.filter { $0.description != "\(character)" }.map { "\($0)" }.joined(separator: "")
  } else {
    newString = newString.characters.filter { $0.description != "\(character)" }.map { "\($0)" }.joined(separator: "")
    }
  }
return newString
}

马丁写了一个比我干净得多的版本,但我在这方面做了一段时间,所以我想我会把它贴出来,向你展示实现它的另一种方式

func removeDuplicates(from original: String) -> String {
var originalString = original
var newString = ""

for character in originalString.characters {
if !newString.contains("\(character)") {
    newString.append(character)
     originalString = originalString.characters.filter { $0.description != "\(character)" }.map { "\($0)" }.joined(separator: "")
  } else {
    newString = newString.characters.filter { $0.description != "\(character)" }.map { "\($0)" }.joined(separator: "")
    }
  }
return newString
}

这将是有序字符串。因为集合是无序的。@RajanMaheshwari:集合仅用于确定哪些字符出现多次。实际筛选在最后一行完成,这保留了字符的顺序。哦..我错过了那个..GreatThank你,你的代码工作得很好。但我需要一个不同的功能。我需要删除e仅包含两次的字符,例如“aaabbaac”->“ac“。当我递归调用func时,我添加了return,它工作正常。@user7092043:好的,那么我误解了你的目标。也许你可以更新你的问题,并用更多的例子来澄清这一点。这将是有序字符串。因为集合是无序的。?@RajanMaheshwari:集合仅用于确定哪些字符出现多次。实际的过滤在最后一行完成,这保留了字符的顺序。哦。。我错过了那个。。谢谢你,你的代码很好用。但我需要一个不同的功能。我只需要删除包含两次的字符,例如“aaabbaac”->“ac”。当我递归调用func时,我添加了return,它工作得很好。@user7092043:好的,那么我误解了你的目标。也许你可以更新你的问题,并用更多的例子来阐明这一点。不要在问题中添加解决方案。您可以回答自己的问题,也可以接受现有答案之一。不要将解决方案添加到问题中。您可以回答自己的问题,也可以接受现有答案之一。