有个6x5二维数组,要求是给定任意一个值,查找出其所在数组中的下标索引x,y

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

二位数组的查找可以通过暴力查找,即双层循环逐行遍历查找

观察数组可以发现,从左到右递增,从上到下递增,在有序的一维数组中,我们可以通过二分法快速查找,同理,二位数组也可以利用这个特性。

我们以右上角5[0,4]点起始点,可以发现比它大的都在下边,比他小的都在左边,于是对于任意目标值 n,如果n<5, 列坐标左移一位继续查找,如果n>5,行坐标下移一位继续查找,如果n==5,那么查找成功,返回下标xy, 如此循环往复,直到行列坐标越界

左上角和右下角则不具备这个特点,同理左下角的点也具备这个查找特点

代码实现

  // led矩阵  
  private val mLed = arrayOf(
        arrayOf(1, 2, 3, 4, 5),
        arrayOf(6, 7, 8, 9, 10),
        arrayOf(11, 12, 13, 14, 15),
        arrayOf(16, 17, 18, 19, 20),
        arrayOf(21, 22, 23, 24, 25),
        arrayOf(26, 27, 28, 29, 30)
    )

 fun transferToXY(end: Int, lightPoint: SpotLightPoint) {
        val mirror = !isLeftSide
        try {
            // 行列
            val cCount = mLed.first().size
            val rCount = mLed.size
            // 从矩阵右上角开始查找
            var column = mLed.first().size - 1
            var row = 0
            while (column >= 0 && row < rCount) {
                println("row = $row, column = $column, value = ${mLed[row][column]}, target = $end")
                if (mLed[row][column] < end) {
                    row +=1
                    println("next row = $row")
                } else if (mLed[row][column] > end) {
                    column -=1
                    println("next column = $column")
                } else {
                    println("transferToXY: find end [$row, $column]")
                    LogUtils.i(TAG, "transferToXY: find end [$row, $column]")
                    // 反转行列到xy
                    lightPoint.x = column
                    lightPoint.y = row
                    println("transferToXY: point = $lightPoint")
                    return
                }
            }
            println("transferToXY: end point does not found")
        } catch (e: Exception) {
            LogUtils.w(TAG, "transferToXY: error " + e.message)
        }
    }

春风花气馥,秋月寒江湛