Swift泛型函数(n选择k)

时间:2014-09-13 09:14:27

标签: generics swift combinations

我试图在Swift中创建这个JavaScript代码:k_combinations

到目前为止,我在Swift中有这个:

import Foundation
import Cocoa

extension Array {
func slice(args: Int...) -> Array {
    var s = args[0]
    var e = self.count - 1
    if args.count > 1 { e = args[1] }

    if e < 0 {
        e += self.count
    }

    if s < 0 {
        s += self.count
    }

    let count = (s < e ? e-s : s-e)+1
    let inc = s < e ? 1 : -1
    var ret = Array()

    var idx = s
    for var i=0;i<count;i++  {
        ret.append(self[idx])
        idx += inc
    }
    return ret
  }
}

func kombinaatiot<T>(setti: Array<T>, k: Int) -> Array<Array<T>> {

var i: Int, j: Int

if (k > setti.count || k <= 0) {
    return []
}

if (k == setti.count) {
    return [setti]
}

if (k == 1) {
    var combs: Array<T> = []

    for var i = 0; i < setti.count; i++ {
        combs += [setti[i]]
    }
    return [combs]
}

var combs: Array<Array<T>> = [[]]

for var i = 0; i < setti.count - k + 1; i++ {
    var head = setti.slice(i,i + 1)
var tailcombs = kombinaatiot(setti.slice(i + 1), k - 1)
    for var j = 0; j < tailcombs.count; j++ {
combs += ([head + tailcombs[j]])

    }
}
    println(combs)
   return combs
}

但问题是我的功能打印

[[], [1, 2, 2, 3, 4], [2, 3, 3, 4], [3, 4, 4]]

何时打印

[[1,2], [1,3], [2, 3]

我在这里做错了什么?我在编码方面很不错,而且我的javascript技能也不是很好,但javascript对我很有用,但是我很快就能做到这一点。

1 个答案:

答案 0 :(得分:2)

Swift翻译中的主要错误是对JavaScript slice(start, end)方法的误解:该方法返回带有索引的元素,该索引从给定的起始索引到但不包括给定结束指数。你的Swift方法包括 结束指数,这是错误的。

但Swift已经使用下标和范围语法内置切片。例如:

let a = [0, 1, 2, 3]
let b = Array(a[1 ..< 3]) // from index 1 up to (but not including) 3
println(b) // [1, 2]

另一个错误是(并且可能已经存在于JavaScript代码中) 对于k == 0,您必须返回[[]],即包含空选择的数组, 而不是[]。事实上,这是唯一必须特别处理的案件。 通过递归自动正确处理所有其他情况。

最后,在一般情况下,你必须从一个空数组开始:

var combs: Array<Array<T>> = [] // not [[]]

这提供了以下方法:

func kombinaatiot<T>(setti: [T], k: UInt) -> [[T]] {

    if k == 0 {
        return [[]]
    }

    var combs: [[T]] = []
    for (i, head) in enumerate(setti) {
        let tailcombs = kombinaatiot(Array(setti[i+1 ..< setti.count]), k - 1)
        for tc in tailcombs {
            combs += [[head] + tc]
        }
    }
    return combs
}

一些评论:

  • [T]Array<T>
  • 的简写符号
  • 我已经取代了&#34; C风格&#34;循环for .. in循环更多&#34; swifty&#34;。
  • k参数声明为无符号整数。