虽然递归扫描通常用于扫描嵌套对象/数据。如果某些对象相互引用,它可以进行无限循环。那么,什么是扫描所有项目的最有效方法,不会崩溃计算机,也不会跳过指定的参数?
这是一个递归扫描仪的例子......
/**
* Triggers the scan function for each object given
**/
function recursiveScanner( object:* , scanFunction:Function ):void {
if( typeof(object) == 'object' ) {
for( var key:String in object ) {
recursiveScanner( object[key], scanFunction );
}
} else {
scanFunction.call(this, object);
}
}
但是,在
中传递以下内容时会出现很大问题//...
obj1.next = obj2;
//...
obj2.next = obj3;
//...
obj3.next = obj1;
//...
recursiveScanner(obj1, scanFuction);
对象将在永恒循环中触发彼此的扫描。那么有办法解决这个问题吗?
我相信C / C ++:每个scanFunction调用都会被添加到一个由扫描的“内存地址”组成的列表中,从而防止重复。这在AS3中甚至可能吗?有更优雅的方式吗?
答案 0 :(得分:10)
使用Dictionary
保留扫描对象列表,如果之前已扫描过,请忽略它们:
/**
* Triggers the scan function for each object given
**/
function recursiveScanner( object:* , scanFunction:Function, ignoreList:Dictonary = null ):void {
// if we have no list, create one
if (!ignoreList) ignoreList = new Dictionary();
// if the item is in the list, we bail
if (ignoreList[object]) return;
// mark the item as scanned before recursing into it
ignoreList[object] = true;
if( typeof(object) == 'object' ) {
for( var key:String in object ) {
recursiveScanner( object[key], scanFunction, ignoreList );
}
} else {
scanFunction.call(this, object);
}
}
答案 1 :(得分:2)
好的,接受@grapefrukt的回答,但这里有一些背景知识。
在计算机科学术语中,问题等同于遍历可能包含循环的directed graph。
基本上有两种天真的方式(即不遵循启发式)来遍历,depth first或breadth first。
我会将其作为练习来确定示例代码是BFS还是DFS。