在Swift中计算不同的字符

时间:2015-12-19 13:48:53

标签: string swift for-loop character

我是swift的新手,我正在尝试count characters中的string,但我的代码会返回整个String

的值

示例

var string aString = "aabb"
aString.characters.count()             //returns 5

counter = 0
let a = "a"

for a in aString.characters {
  counter++
}                                      //equally returns 5

有人可以解释为什么会这样,以及我如何计算不同的字符

6 个答案:

答案 0 :(得分:12)

看起来你真正需要的东西有些混乱。

我试图回答5种最可能的解释。

def rollforward(self, dt):
    """Roll provided date forward to next offset only if not on offset"""
    dt = as_timestamp(dt)
    if not self.onOffset(dt):
        dt = dt + self.__class__(1, normalize=self.normalize, **self.kwds)
    return dt

答案 1 :(得分:7)

检查这个

var aString = "aabb"
aString.characters.count // 4

var counter = 0
let a = "a" // you newer use this in your code 

for thisIsSingleCharacterInStringCharactersView in aString.characters {
    counter++
}
print(counter) // 4

它只会增加每个角色的计数器

计算字符串中不同字符的数量,您可能可以使用“更高级”的内容,如下例所示

let str = "aabbcsdfaewdsrsfdeewraewd"

let dict = str.characters.reduce([:]) { (d, c) -> Dictionary<Character,Int> in
    var d = d
    let i = d[c] ?? 0
    d[c] = i+1
    return d
}
print(dict) // ["b": 2, "a": 4, "w": 3, "r": 2, "c": 1, "s": 3, "f": 2, "e": 4, "d": 4]

答案 2 :(得分:2)

您的代码非常错误:它应该以

开头
let aString = "aabb"

解决方案是获取字符,将它们放入集合(唯一)中,然后计算集合的成员:

let differentChars = Set(aString.characters).count

正确退货

  

2

答案 3 :(得分:1)

不推荐使用characters属性,可以使用components(separatedBy:)查找一个字符串中有多少个字符。例如,

extension String {

    public func numberOfOccurrences(_ string: String) -> Int {
        return components(separatedBy: string).count - 1
    }

}
let aString = "aabbaa"
let aCount = aString.numberOfOccurrences("a") // aCount = 4

答案 4 :(得分:0)

更新了@Luca Angeletti 对 Swift5.3 的回答,因为 characters 属性在较新的 Swift 版本中不可用。

var word = "aabb"

let numberOfChars = word.count // 4
let numberOfDistinctChars = Set(word).count // 2
let occurrenciesOfA = word.filter { $0 == "A" }.count // 0
let occurrenciesOfa = word.filter { $0 == "a" }.count // 2
let occurrenciesOfACaseInsensitive = word.filter { $0 == "A" || $0 == "a" }.count // 2

print(numberOfChars)
print(numberOfDistinctChars)
print(occurrenciesOfA)
print(occurrenciesOfa)
print(occurrenciesOfACaseInsensitive)

答案 5 :(得分:-1)

此解决方案使用哈希函数编写,因此计算时间为O(1)。适合长串。

//扩展字符串和字符以从Ascii获取Ascii值和Char

extension Character {
    //Get Ascii Value of Char
    var asciiValue:UInt32? {
        return String(self).unicodeScalars.filter{$0.isASCII}.first?.value
    }
}

extension String {
    //Char Char from Ascii Value
    init(unicodeScalar: UnicodeScalar) {
        self.init(Character(unicodeScalar))
    }


init?(unicodeCodepoint: Int) {
    if let unicodeScalar = UnicodeScalar(unicodeCodepoint) {
        self.init(unicodeScalar: unicodeScalar)
    } else {
        return nil
    }
}


static func +(lhs: String, rhs: Int) -> String {
    return lhs + String(unicodeCodepoint: rhs)!
}


static func +=(lhs: inout String, rhs: Int) {
    lhs = lhs + rhs
}
}

extension String {
    ///Get Char at Index from String
    var length: Int {
        return self.characters.count
    }

subscript (i: Int) -> String {
    return self[Range(i ..< i + 1)]
}

func substring(from: Int) -> String {
    return self[Range(min(from, length) ..< length)]
}

func substring(to: Int) -> String {
    return self[Range(0 ..< max(0, to))]
}

subscript (r: Range<Int>) -> String {
    let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                        upper: min(length, max(0, r.upperBound))))
    let start = index(startIndex, offsetBy: range.lowerBound)
    let end = index(start, offsetBy: range.upperBound - range.lowerBound)
    return self[Range(start ..< end)]
}

}

//程序:

let  strk = "aacncjkvkevkklvkdsjkbvjsdbvjkbsdjkvbjdsbvjkbsvbkjwlnkneilhfleknkeiohlgblehgilkbskdbvjdsbvjkdsbvbbvsbdvjlbsdvjbvjkdbvbsjdbjsbvjbdjbjbjkbjkvbjkbdvjbdjkvbjdbvjdbvjbvjdsbjkvbdsjvbkjsbvadvbjkenevknkenvnekvjksbdjvbjkbjbvbkjvbjdsbvjkbdskjvbdsbvjkdsbkvbsdkjbvkjsbvjsbdjkvbdsbvjkbdsvjbdefghaj"

print(strk)

//Declare array of fixes size 26 (characters) or you can say it as a hash table 
var freq = [Int](repeatElement(0, count: 26))

func hashFunc(char : Character) -> UInt32 {
    guard let ascii = char.asciiValue else {
        return 0
    }
    return ascii - 97 //97 used for ascii value of a
}


func countFre(string:String) {

    for i in 0 ... string.characters.count-1 {
        let charAtIndex = string[i].characters.first!
        let index = hashFunc(char: charAtIndex)
        let currentVal = freq[Int(index)]
        freq[Int(index)] = currentVal + 1
        //print("CurrentVal of \(charAtIndex) with index \(index) is \(currentVal)")

    }

    for charIndex in 0 ..< 26 {
        print(String(unicodeCodepoint: charIndex+97)!,freq[charIndex])
    }
}

countFre(string: strk)