Swift版全排列-Heap's Algorithm

Swift 全排列算法,递归版和非递归版,都有! 参考于Wiki-Heap's algorithm

很有Swift特色,不是简单的翻译而已,废话不多说,直接上代码(Swift3+):

import Foundation

/// 递归全排列
func heapsAlgorithmPermutationRecursive<T: Collection>(list: T) -> [[T.Iterator.Element]] {
    var result: [[T.Iterator.Element]] = []
    var temp = Array(list)
    // Heap's Algorithm recursive
    func heap(n: Int) {
        if n == 1 {
            result.append(temp)
        }else {
            for i in 0..<n-1 {
                heap(n: n-1)
                swap(&temp[n%2 == 0 ? i : 0], &temp[n-1])
            }
            heap(n: n-1)
        }
    }
    // start
    heap(n: temp.count)
    return result
}

/// 非递归全排列
func heapsAlgorithmPermutationNonRecursive<T: Collection>(list: T) -> [[T.Iterator.Element]] {
    var result: [[T.Iterator.Element]] = []
    var temp = Array(list)
    var index = [Int](repeating: 0, count: temp.count)
    var i = 0
    // Heap's Algorithm non-recursive
    result.append(temp)
    while i < temp.count {
        if index[i] < i {
            swap(&temp[i%2 == 0 ? 0 : index[i]], &temp[i])
            result.append(temp)
            index[i] += 1
            i = 0
        }else {
            index[i] = 0
            i += 1
        }
    }
    return result
}


// 测试数据
//let list = Array(1...7)
var list = "abc".characters
var date = NSDate()
var result: [[Any]]

// 递归
result = heapsAlgorithmPermutationRecursive(list: list)
print("递归:\ncount:\(result.count)\n耗时:\(date.timeIntervalSinceNow)")
print(result)

// 非递归
date = NSDate()
result = heapsAlgorithmPermutationNonRecursive(list: list)
print(date.timeIntervalSinceNow)
print("非递归:\ncount:\(result.count)\n耗时:\(date.timeIntervalSinceNow)")
print(result)


// 去重测试
list = "abb".characters
result = heapsAlgorithmPermutationNonRecursive(list: list)
print("未去重前结果:\n\(result)")

let combine = result.flatMap { (c) -> String in
    let r = c as! [Character]
    return r.reduce("") {a,b in
        a + String(b)
    }
}
let norepeat = Set(combine)
print("去重后:\n\(norepeat)")

转载于:https://my.oschina.net/jeans/blog/794894

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值