新增 选择器搜索算法BFS(广度优先搜索)

This commit is contained in:
hyb1996 2018-12-04 13:37:34 +08:00
parent 4b3d4ab84c
commit 1ff36a799d
7 changed files with 107 additions and 55 deletions

View File

@ -3,6 +3,10 @@ package com.stardust.automator
import android.graphics.Rect
import android.os.Build
import com.stardust.automator.filter.*
import com.stardust.automator.search.BFS
import com.stardust.automator.search.DFS
import com.stardust.automator.search.SearchAlgorithm
import java.lang.IllegalArgumentException
/**
* Created by Stardust on 2017/3/8.
@ -11,6 +15,7 @@ import com.stardust.automator.filter.*
open class UiGlobalSelector {
private val mSelector = Selector()
private var mSearchAlgorithm: SearchAlgorithm = DFS
//// 第一类筛选条件
@ -399,9 +404,6 @@ open class UiGlobalSelector {
return findOf(node, Int.MAX_VALUE)
}
fun findAndReturnList(node: UiObject, max: Int = Int.MAX_VALUE): List<UiObject> {
return DFS(mSelector, max).search(node)
}
fun findOneOf(node: UiObject): UiObject? {
val collection = findOf(node, 1)
@ -415,6 +417,23 @@ open class UiGlobalSelector {
return this
}
fun algorithm(algorithm: String): UiGlobalSelector {
if (algorithm.equals("BFS", true)) {
mSearchAlgorithm = BFS
return this
}
if (algorithm.equals("DFS", true)) {
mSearchAlgorithm = DFS
return this
}
throw IllegalArgumentException("unknown algorithm: $algorithm")
}
fun findAndReturnList(node: UiObject, max: Int = Int.MAX_VALUE): List<UiObject> {
return mSearchAlgorithm.search(node, mSelector, max)
}
override fun toString(): String {
return mSelector.toString()
}

View File

@ -1,10 +0,0 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
class BFS(val filter: Filter, val limit: Int = Int.MAX_VALUE) {
fun search(node: UiObject) {
}
}

View File

@ -1,42 +0,0 @@
package com.stardust.automator.filter
import com.stardust.automator.UiObject
import java.util.ArrayList
/**
* Created by Stardust on 2017/3/9.
*/
class DFS(val filter: Filter, val limit: Int = Int.MAX_VALUE) {
fun search(node: UiObject): List<UiObject> {
val list = ArrayList<UiObject>()
if (filter.filter(node)) {
list.add(node)
if (list.size >= limit) {
return list
}
}
filterChildren(node, list)
return list
}
private fun filterChildren(parent: UiObject, list: MutableList<UiObject>) {
for (i in 0 until parent.childCount) {
val child = parent.child(i) ?: continue
val included = filter.filter(child)
if (included) {
list.add(child)
if (list.size >= limit) {
break
}
}
filterChildren(child, list)
if (!included) {
child.recycle()
}
}
}
}

View File

@ -0,0 +1,32 @@
package com.stardust.automator.search
import com.stardust.automator.UiObject
import com.stardust.automator.filter.Filter
import java.util.*
import kotlin.collections.ArrayList
object BFS : SearchAlgorithm {
override fun search(root: UiObject, filter: Filter, limit: Int): ArrayList<UiObject> {
val result = ArrayList<UiObject>()
val queue = ArrayDeque<UiObject>()
queue.add(root)
while (!queue.isEmpty()) {
val top = queue.poll()
val isTarget = filter.filter(top)
if (isTarget) {
result.add(top)
if (result.size > limit) {
return result
}
}
for (i in 0 until top.childCount) {
queue.add(top.child(i) ?: continue)
}
if (!isTarget && top !== root) {
top.recycle()
}
}
return result
}
}

View File

@ -0,0 +1,43 @@
package com.stardust.automator.search
import com.stardust.automator.UiObject
import com.stardust.automator.filter.Filter
import kotlin.collections.ArrayList
/**
* Created by Stardust on 2017/3/9.
*/
object DFS : SearchAlgorithm {
override fun search(root: UiObject, filter: Filter, limit: Int): ArrayList<UiObject> {
val list = ArrayList<UiObject>()
if (filter.filter(root)) {
list.add(root)
if (list.size >= limit) {
return list
}
}
searchChildren(root, list, filter, limit)
return list
}
private fun searchChildren(parent: UiObject, list: MutableList<UiObject>, filter: Filter, limit: Int) {
for (i in 0 until parent.childCount) {
val child = parent.child(i) ?: continue
val isTarget = filter.filter(child)
if (isTarget) {
list.add(child)
if (list.size >= limit) {
break
}
}
searchChildren(child, list, filter, limit)
if (!isTarget) {
child.recycle()
}
}
}
}

View File

@ -0,0 +1,9 @@
package com.stardust.automator.search
import com.stardust.automator.UiObject
import com.stardust.automator.filter.Filter
interface SearchAlgorithm {
fun search(root: UiObject, filter: Filter, limit: Int = Int.MAX_VALUE): ArrayList<UiObject>
}

View File

@ -2,6 +2,7 @@ package com.stardust.automator.filter
import com.stardust.automator.test.TestUiObject
import com.stardust.automator.UiObject
import com.stardust.automator.search.DFS
import org.junit.Test
import java.util.Random