我在Xcode Playground中尝试使用此代码时注意到description
getter方法被调用了太多次。
代码在这里:https://gist.github.com/T-Pham/4b72d17851162a32b2fc534f0618135d
首先使用print
行,代码运行3176次。
然后在第一个print
注释掉的情况下,代码运行3164次。
这意味着第一个print
必须运行代码12次。
然而,
它是148次。
答案 0 :(得分:4)
这是操场上弄乱你的头。
Playground正在计算自己对具有CustomStringConvertibe协议的变量的调用(可能是为了在右侧面板上提供信息)。
如果您只是调用镜像(树)而根本不打印,则可以看到这种情况。
如果使用自己的计数器计算实际调用次数,则会产生非常不同的结果:
var descCount = 0
extension Node: CustomStringConvertible {
var description: String
{
descCount += 1
return "id: \(id)\nleft: \(left)\nright: \(right)"
}
}
descCount = 0
print(tree)
descCount // 12
descCount = 0
print(mirror(tree))
descCount // 12
顺便说一句,我在理解mirror()函数时遇到了一些麻烦,我认为递归的函数可能更容易理解。如何向Node添加mirror()函数:
func mirror() -> Node
{
let result = Node()
result.id = id
result.left = right?.mirror()
result.right = left?.mirror()
return result
}
print(tree.mirror())
[编辑]这里是一个非递归镜像函数(与你的逻辑逻辑相同),结构更清晰:
func mirror2(tree:Node) -> Node
{
// will return top of mirrored tree
let newTree = Node()
// node pair used for traversal and duplication
var original:Node! = tree
var mirrored:Node! = newTree
// traversal of tree structure left side first
// (uses mirrored tree to keep track of traversed nodes)
while original != nil
{
// carry node identifier (and contents eventually)
mirrored.id = original.id
// downwards, mirror left side first (if not already done)
if (original.left == nil) != (mirrored.right == nil)
{
original = original.left
mirrored.right = Node()
mirrored = mirrored.right
continue
}
// downwards, mirror right side second (if not already done)
if (original.right == nil) != (mirrored.left == nil)
{
original = original.right
mirrored.left = Node()
mirrored = mirrored.left
continue
}
// upwards from leaves and completed branches
original = original.parent
mirrored = mirrored.parent
}
return newTree
}
和树形描述的一些视觉糖果:
extension Node: CustomStringConvertible
{
var indent:String
{ return " " + (parent?.indent ?? "") }
var description: String
{
return "\(id)\n"
+ ( left != nil ? "\(indent)L:\(left!)" : "" )
+ ( right != nil ? "\(indent)R:\(right!)" : "" )
}
}
可以更轻松地比较结果:
print(tree)
// 0
// L:1
// L:3
// L:7
// R:8
// R:4
// L:9
// R:10
// R:2
// R:6
// L:13
// R:14
//
print(mirror2(tree))
// 0
// L:2
// L:6
// L:14
// R:13
// R:1
// L:4
// L:10
// R:9
// R:3
// L:8
// R:7