You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Kotlin函数式方式提取n阶矩阵中的m阶重叠子矩阵(m<n)

Kotlin函数式提取矩阵中m阶重叠子矩阵

给定示例矩阵:

val matrix = listOf(
    listOf(1, 2, 3, 4),
    listOf(5, 6, 7, 8),
    listOf(9, 1, 2, 3)
)

要提取所有m×m大小的重叠子矩阵,可以利用Kotlin标准库的windowed函数实现纯函数式写法,甚至可以压缩为一行代码。

核心实现(一行代码)

matrix.windowed(m).flatMap { rowWindow -> rowWindow.map { it.windowed(m) }.let { colWindows -> colWindows.first().indices.map { c -> colWindows.map { it[c] } } } }

分步解释

  1. 获取行窗口:matrix.windowed(m) 提取原矩阵中连续m行的滑动窗口,每个窗口是一个包含m行的子矩阵(List<List<Int>>)。
  2. 拆分每行的列窗口:对每个行窗口,rowWindow.map { it.windowed(m) } 将每行拆分为长度为m的滑动窗口,得到一个List<List<List<Int>>>结构——外层是m行,中层是每行的所有m长度列窗口。
  3. 组合子矩阵:通过colWindows.first().indices.map { c -> colWindows.map { it[c] } },将m行中同一位置的列窗口组合成完整的m×m子矩阵,最后用flatMap将所有子矩阵平铺到一个列表中。

补充:转置扩展函数简化写法

如果觉得一行代码过于紧凑,可以定义一个转置扩展函数来优化可读性:

fun <T> List<List<T>>.transpose(): List<List<T>> {
    return first().indices.map { colIndex -> map { it[colIndex] } }
}

此时提取子矩阵的代码可以简化为:

matrix.windowed(m).flatMap { it.map { row -> row.windowed(m) }.transpose() }

验证示例(m=3)

对于给定的3行4列矩阵,m=3时会得到两个3×3子矩阵:

  1. [[1,2,3], [5,6,7], [9,1,2]]
  2. [[2,3,4], [6,7,8], [1,2,3]]

原命令式代码的问题修正

原命令式代码存在几处错误,修正后如下:

val result = mutableListOf<List<List<Int>>>()
val rowCount = matrix.size
val colCount = matrix.first().size
for (i in 0 until rowCount - m + 1) {
    for (j in 0 until colCount - m + 1) {
        val subMatrix = mutableListOf<List<Int>>()
        for (k in i until i + m) {
            val row = mutableListOf<Int>()
            for (l in j until j + m) {
                row.add(matrix[k][l])
            }
            subMatrix.add(row)
        }
        result.add(subMatrix)
    }
}
  • 修正了循环范围:需用until rowCount - m + 1才能覆盖所有可能的起始位置
  • 修正了元素引用:matrix[m][n]改为matrix[k][l]
  • 改为真正的二维子矩阵存储,而非一维列表

内容的提问来源于stack exchange,提问作者Alexander Ites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:54:59