我有这个在JavaScript中正常工作的递归函数:
var distributeSpacings = function (cols, maxSpacing) {
if (cols == 1) {
return [maxSpacing];
}
var results = [];
for (var i = 0; i <= maxSpacing; i++) {
var subSpacings = distributeSpacings(cols - 1, maxSpacing - i);
for (var j = 0; j < subSpacings.length; j++) {
var subSpacing = subSpacings[j];
results.push([i].concat(subSpacing));
}
}
return results;
}
console.log(distributeSpacings(3, 3));
// prints:
// [ [ 0, 0, 3 ],
// [ 0, 1, 2 ],
// [ 0, 2, 1 ],
// [ 0, 3, 0 ],
// [ 1, 0, 2 ],
// [ 1, 1, 1 ],
// [ 1, 2, 0 ],
// [ 2, 0, 1 ],
// [ 2, 1, 0 ],
// [ 3, 0, 0 ] ]
我想在Swift中编写它。类型安全使这很困难 - 这就是我到目前为止所做的:
extension Array {
func concat(toAdd: Any) -> [Element] {
if let _ = toAdd as? Int {
return self + ([toAdd as! Element])
} else {
return self + (toAdd as! [Element])
}
}
}
func permutateSpacings (columns: Int, maxSpacing: Int) -> Any {
if columns == 1 {
return [maxSpacing]
}
var results = [Any]()
for (var i = 0; i <= maxSpacing; i++) {
var subSpacings = permutateSpacings(columns - 1, maxSpacing: maxSpacing - 1) as! [Int] // I suspect the problem is with this line
for (var j = 0; j < subSpacings.count; j++) {
let subSpacing = subSpacings[j]
results.append([i].concat(subSpacing))
}
}
return results
}
print(permutateSpacings(3, maxSpacing: 3) as! [[Int]])
// prints:
// Could not cast value of type 'Swift.Array<protocol<>>' (0x1175ef0d8) to 'Swift.Array<Swift.Int>' (0x1175ef028).
答案 0 :(得分:3)
所以我设法通过一些调整来修复你的功能。
第一个问题是您的函数返回Any
而不是[Any]
。然后你将Any
转换为[Int]
,然后发生了崩溃。第二个问题是你的隐式转换as! [Int]
。使用!
而guard
/ if let
(在可能崩溃的地方,这里确实可以),这是一种不好的做法,你真的不喜欢无论如何都需要施展。第三个问题在于:
var subSpacings = permutateSpacings(columns - 1, maxSpacing: maxSpacing - 1)
你有1
而不是需要i
(来自你的JS算法)。工作职能如下:
extension Array {
func concat(toAdd: Any) -> [Element] {
if let _ = toAdd as? Int {
return self + ([toAdd as! Element])
} else {
return self + (toAdd as! [Element])
}
}
}
func permutateSpacings (columns: Int, maxSpacing: Int) -> [Any] {
if columns == 1 {
return [maxSpacing]
}
var results = [Any]()
for (var i = 0; i <= maxSpacing; i++) {
var subSpacings = permutateSpacings(columns - 1, maxSpacing: maxSpacing - i)
for (var j = 0; j < subSpacings.count; j++) {
let subSpacing = subSpacings[j]
results.append([i].concat(subSpacing))
}
}
return results
}
print(permutateSpacings(3, maxSpacing: 3))
答案 1 :(得分:1)
感谢阳光寻找1
- &gt; i
。我得到了不同的结果,并认为我弄乱了算法。
不需要你的数组扩展,但它会像这样正确编写:
extension Array {
func concat(toAdd: [Element]) -> [Element] {
return self + toAdd
}
func concat(toAdd: Element) -> [Element] {
return self + [toAdd]
}
}
根本不需要Any
。类型总是已知的。
for spacing in 0...maxSpacing
for subSpacing in subSpacings
迭代的更快的语法。
func permutateSpacings(columns: Int, maxSpacing: Int) -> [[Int]] {
if columns == 1 {
return [[maxSpacing]]
}
var results : [[Int]] = [] // var/let : Type = Value
for spacing in 0...maxSpacing {
let subSpacings = permutateSpacings(columns - 1, maxSpacing: maxSpacing - spacing)
for subSpacing in subSpacings {
results.append(([spacing] + subSpacing))
}
}
return results
}