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

C语言中多维数组特定0模式匹配的高效算法求解

高效0-1矩阵模式匹配算法(仅匹配pattern中的0)

核心匹配规则

先明确需求边界:

  • 仅当pattern的行数P_rows ≤ M_rows且列数P_cols ≤ M_cols时执行匹配(若要求严格小于,只需调整坐标范围为x ∈ [0, M_rows-P_rows)、y ∈ [0, M_cols-P_cols))
  • 匹配成功条件:match中任意P_rows×P_cols的子矩阵,所有对应pattern为0的位置必须是0;pattern为1的位置,子矩阵对应元素可0可1,不影响匹配

针对超大矩阵(1e6×1e6)的高效方案

由于1e6×1e6的矩阵无法直接存储完整前缀和(内存需求达数TB),必须选择低内存、高效率的算法,以下两种方案按需选择:

方案1:禁止位置标记法(优先推荐,适配稀疏/稠密矩阵)

思路

匹配失败的子矩阵,必然是其覆盖范围内存在某个1的位置,正好对应pattern中的0位置。我们只需找出所有这类无效子矩阵,用总候选数减去无效数即可得到匹配数。

步骤

  1. 计算总候选数:若P_rows > M_rows或P_cols > M_cols,直接返回0;否则总候选数total = (M_rows - P_rows + 1) * (M_cols - P_cols + 1)
  2. 提取pattern的0位置:记录所有(dx, dy),其中pattern[dx][dy] == 0(记为集合zero_pos)。若zero_pos为空,说明pattern全是1,所有候选子矩阵都匹配,直接返回total
  3. 收集match的1位置:遍历match矩阵,记录所有(a, b),其中match[a][b] == 1(记为集合ones)
  4. 标记无效子矩阵:
    • 对每个1的位置(a, b),遍历zero_pos中的每个(dx, dy)
    • 计算无效子矩阵的左上角坐标x = a - dx,y = b - dy
    • 若x在[0, M_rows-P_rows]范围内,且y在[0, M_cols-P_cols]范围内,将(x, y)加入无效集合(用哈希集合或位图分块去重)
  5. 计算匹配数:match_count = total - len(无效集合)

优势

  • 内存占用极低:无需存储完整match矩阵或前缀和,仅需存储稀疏的1位置和无效子矩阵位置
  • 效率可控:match中1越少,算法越快;即使1较多,位图分块也能高效存储无效位置

方案2:流式滑动窗口法(适配pattern较小的场景)

若pattern的行数P_rows较小(如≤1000),可采用流式处理,避免存储完整match矩阵:

步骤

  1. 预处理pattern行信息:对pattern的每一行,记录该行中0的列索引集合row_zero[dx](dx为行号)
  2. 流式处理match行:
    • 维护一个大小为P_rows的窗口,存储最近P_rows行的列滑动窗口求和结果
    • 对每一行i,计算该行每个列起始位置y的求和值:row_sum[y] = sum(match[i][y+dy] for dy in row_zero[dx]),其中dx是当前行在窗口中的相对行号
  3. 列滑动窗口校验:对每个列起始位置y,维护最近P_rows行的row_sum[y]之和,若总和为0,说明该子矩阵匹配成功,计数加1

优势

  • 流式处理,无需存储完整match矩阵,内存占用仅为O(P_rows * M_cols)
  • 适合pattern较小、match为稠密矩阵的场景

示例验证

用你给出的示例:

  • pattern的zero_pos = {(0,0), (1,0), (1,1)}
  • match的1位置为(0,1), (0,3), (2,0), (2,4)
  • 总候选数total = (3-2+1)*(5-2+1) = 8
  • 标记的无效子矩阵为(0,1), (0,3), (1,0), (1,3),共4个
  • 匹配数8-4=4,与示例结果一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:20:44