如何在Swift中找到字符串的所有大小写组合?

368yc8dk  于 2022-12-10  发布在  Swift
关注(0)|答案(3)|浏览(125)

Problem

I'm trying to find all of the possible combinations of capitalization for a String in Swift. For example, given the String "abc", I would want my method to return an Array of String s, like this: ["Abc", "aBc", "abC", "ABc", "abc", "ABC", "aBC", "AbC"] . The formula for the possible number of capitalization combinations is like this:
2i
where i is the number of Characters in the String .

Attempted Solutions

I've tried the following function, via an extension to the String type:

extension String {
func allPossibleCombinations() -> [String] {
        let string = self
        var result = [String]()
        var current = string
        result.append(current)
        for i in 0..<string.count {
            let index = string.index(string.startIndex, offsetBy: i)
            if string[index].isLetter {
                current = current.replacingCharacters(in: index...index, with: String(current[index]).uppercased())
                result.append(current)
            }
        }
        return result
    }

}

This didn't work because it only returns capitalizations in order. For example, if I were to call this method on the String"abc" , it would return

["abc", "Abc", "ABc", "ABC"]

This should produce, as stated above, 8 different Strings . I suspect that I need to factor in an exponent to my code, or potentially some form of randomly choosing a Character .

Similar questions that are NOT duplicates

Summary

I am trying to make a function to get all possible capitalization forms of a String . I have a current attempt, but it is not sufficient as it does not produce all possible options.

l5tcr1uw

l5tcr1uw1#

计算0 ..< 2^length范围内的整数,并使用二进制表示的位来告诉您何时将字母大写:

extension String {
    func allPossibleCombinations() -> [String] {
        guard self.count > 0 else { return [] }
        var result = [String]()
        let lower = self.lowercased().map(String.init)
        let upper = self.uppercased().map(String.init)
        let length = self.count
        let limit = 1 << length
        for n in 0..<limit {
            var word = ""
            for i in 0..<length {
                if n & (1 << (length - i - 1)) != 0 {
                    word += upper[i]
                } else {
                    word += lower[i]
                }
            }
            result.append(word)
        }
        return result
    }
}

示例

print("abc".allPossibleCombinations())

// ["abc", "abC", "aBc", "aBC", "Abc", "AbC", "ABc", "ABC"]

print("abcd".allPossibleCombinations())

// ["abcd", "abcD", "abCd", "abCD", "aBcd", "aBcD", "aBCd", "aBCD", "Abcd", "AbcD", "AbCd", "AbCD", "ABcd", "ABcD", "ABCd", "ABCD"]

Alex的快速版
在评论中,Alex使用嵌套Map添加了这个Swifty版本:

extension String {
    func allPossibleCombinations() -> [String] {
        guard self.count > 0 else { return [] }

        let length = self.count
        let limit = 1 << self.count
        
        return (0..<limit) .map { n in
            return self.enumerated()
                .map { i, c in (n & (1 << (length - i - 1)) != 0) ? c.uppercased() : c.lowercased() }
                .joined()
        }
    }
}
vc9ivgsu

vc9ivgsu2#

您可以遵循递归方法:

func capitalizations(of string: String) -> [String] {
    guard let first = string.first else { return [] }

    let firstLowercase = first.lowercased()
    let firstUppercase = first.uppercased()

    if string.count == 1 {
        return [firstLowercase, firstUppercase]
    } else {
        let partial = capitalizations(of: String(string.dropFirst()))
        return partial.map { firstLowercase + $0 } + partial.map { firstUppercase + $0 }
    }
}

print(capitalizations(of: "abc"))
// ["abc", "abC", "aBc", "aBC", "Abc", "AbC", "ABc", "ABC"]

只需要取第一个字符,将其小写和大写,并将其前置到字符串其余部分的大写字母中。

doinxwow

doinxwow3#

使用uniquePermutations

import Algorithms

extension String {
  var capitalizationCombinations: [Self] {
    [false, true].flatMap {
      capitalize in repeatElement(capitalize, count: count)
    }
    .uniquePermutations(ofCount: count)
    .map { [lowercased = lowercased()] capitalizes in
      .init(
        zip(lowercased, capitalizes).map { character, capitalize in
          capitalize ? character.uppercased().first! : character
        }
      )
    }
  }

相关问题