stackoverflow.com/a/34969388/1187415

1, Swift 4.0

Попытка написать рекурсивную функцию, чтобы показать все возможные комбинации строки. Я получил это, но это не совсем правильно, так как я получаю только 20 пар, а я должен получить 24. Я не вижу, что я здесь пропустил.

Где эта кодировка идет не так?

var ans:Set<String>!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let str = "ABCD"
    ans = []
    recursiveString(s2s: str, char2s: 0)
    print("\(ans) \(ans.count)")
}

func recursiveSwap(s2x: String, c2x: Int, j2m: Int) {
    var anschr = Array(s2x)
        let tmpchr = anschr[c2x]
        anschr[c2x] = anschr[c2x+j2m]
        anschr[c2x+j2m] = tmpchr
        print("\(String(anschr))")
            ans.insert(String(anschr))
        if (c2x + j2m + 1) < s2x.count {
            recursiveSwap(s2x: String(s2x), c2x: c2x, j2m: j2m+1)
        } else {
            if (c2x + 1) < s2x.count - 1 {
                recursiveSwap(s2x: String(anschr), c2x: c2x + 1, j2m: 1)
            }
        }
}

func recursiveString(s2s: String, char2s: Int) {
    let blue = shiftString(s2s: s2s)
    if char2s < s2s.count {
        recursiveSwap(s2x: blue, c2x: 0, j2m: 1)
        recursiveString(s2s: blue, char2s: char2s + 1)
    }
}

func shiftString(s2s: String) -> String {
    let str2s = Array(s2s)
    let newS = str2s.suffix(str2s.count - 1)  + str2s.prefix(1)
    return String(newS)
}

Это даст мне ...

CBDA DCBA ACDB ADCB ABDC ABCD DCAB ADCB BDAC BADC BCAD BCDA ADBC ​​BADC CABD CBAD CDBA CDAB BACD CBAD DBCA DCBA DACB DABC

 Adrian05 нояб. 2017 г., 01:02
В будущем вы можете заглянуть в Swift Algorithm Club на Github. Есть много популярных алгоритмов с объяснениями и кодом.github.com/raywenderlich/swift-algorithm-club
 Martin R04 нояб. 2017 г., 21:40
Интересно, почему кто-то голосует за закрытие не по теме, потому что «вопросы, требующие помощи в отладке ... должны включать в себя желаемое поведение, конкретную проблему или ошибку и самый короткий код, необходимый для воспроизведения его в самом вопросе». - Все этоявляется присутствует в этом вопросе.
 user306923205 нояб. 2017 г., 06:38
Да, вы правы, это дубликат, который я не нашел в SO, когда искал его ранее. Хотя мне нравится ответ Лео, это действительно чистый и понятный кусок кода. Спасибо Адриану, я тоже посмотрю на клуб алгоритмов лучей.
 vacawama04 нояб. 2017 г., 21:26
 matt05 нояб. 2017 г., 00:36

Ответы на вопрос(2)

Trying to write a recursive function to show all the possible combinations of a string

Я думаю, вы могли бы так что-то вроде этого:

// Takes any collection of T and returns an array of permutations
func permute<C: Collection>(items: C) -> [[C.Iterator.Element]] {
    var scratch = Array(items) // This is a scratch space for Heap's algorithm
    var result: [[C.Iterator.Element]] = [] // This will accumulate our result

    // Heap's algorithm
    func heap(_ n: Int) {
        if n == 1 {
            result.append(scratch)
            return
        }

        for i in 0..<n-1 {
            heap(n-1)
            let j = (n%2 == 1) ? 0 : i
            scratch.swapAt(j, n-1)
        }
        heap(n-1)
    }

    // Let's get started
    heap(scratch.count)

    // And return the result we built up
    return result
}

// We could make an overload for permute() that handles strings if we wanted
// But it's often good to be very explicit with strings, and make it clear
// that we're permuting Characters rather than something else.

let string = "ABCD"
let perms = permute(string.characters) // Get the character permutations
let permStrings = perms.map() { String($0) } // Turn them back into strings
print(permStrings) // output if you like

Извлеченный из этого ответа, который однажды мне очень помог:Вычислить все перестановки строки в Swift

Это даст вам ряд перестановок.

Я надеюсь, это поможет вам.

 user306923205 нояб. 2017 г., 06:33
Габокс, спасибо за ответ! Я бы тоже отметил твой ответ, но ТАК заставляет меня выбрать один. Они оба - лучшие части кода, которые мне удалось придумать ...
 Martin R05 нояб. 2017 г., 10:21
Это не похоже, нодословная копия кода вstackoverflow.com/a/34969388/1187415.
Решение Вопроса

но вы можете получить всеперестановки (перевод с Java на Свифт) следующим образом:

public extension StringProtocol where Self: RangeReplaceableCollection {
    public var permutations: Set<String> {
        guard !isEmpty else { return [] }
        permutate(Self(), self[...])
        return String.permutations
    }
    private func permutate(_ result: Self, _ string: SubSequence) {
        if string.isEmpty {
            String.permutations.insert(result.string)
        } else {
            string.lazy.indices.forEach {
                permutate(result + [string[$0]], string[..<$0] + string[string.index(after: $0)...])
            }
        }
    }
}
fileprivate extension String {
    fileprivate static var permutations: Set<String> = []
}
public extension LosslessStringConvertible {
    public var string: String { return String(self) }
}
let str = "ABCD"
print(str.permutations.sorted())   // "["ABCD", "ABDC", "ACBD", "ACDB", "ADBC", "ADCB", "BACD", "BADC", "BCAD", "BCDA", "BDAC", "BDCA", "CABD", "CADB", "CBAD", "CBDA", "CDAB", "CDBA", "DABC", "DACB", "DBAC", "DBCA", "DCAB", "DCBA"]\n"

Мутация подстроки

let permutations = "ABCD".dropLast().permutations  // {"CBA", "ABC", "BCA", "ACB", "BAC", "CAB"}
print(permutations.sorted())   // ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"]\n"

Ваш ответ на вопрос