首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C 語言圖像處理:字符矩陣中矩形檢測算法與實現策略

     編輯:C 語言問答

C 語言圖像處理:字符矩陣中矩形檢測算法

給定 80×50 字符矩陣(* 代表前景,空格/其他代表背景),檢測是否存在由 * 組成的實心矩形。本文提供三種複雜度遞減的算法策略,並給出關鍵 C 實現細節。

問題形式化

  • 輸入:char img[50][80](50 行,80 列)
  • 目標:判斷是否存在子矩形 (r1,c1) ~ (r2,c2),使得該區域內所有字符均為 *
  • 輸出:存在輸出 1 與座標,否則 0

算法一:暴力枚舉所有矩形 —— O(R²C²) = 1.6×10⁹ (不可行)


// 概念代碼,僅供理解複雜度
for (r1=0; r1

算法二:直方圖 + 單調棧 —— O(R×C) = 4000 (最優)

將每行視為直方圖底部,高度 = 連續 * 向上延伸的列數。經典「最大矩形面積」問題變體。


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define ROWS 50
#define COLS 80

bool detect_rectangle(char img[ROWS][COLS], int *out_r1, int *out_c1, int *out_r2, int *out_c2) {
    int height[COLS] = {0};
    int stack[COLS], top;

    for (int r = 0; r < ROWS; r++) {
        // 更新直方圖高度
        for (int c = 0; c < COLS; c++) {
            height[c] = (img[r][c] == '*') ? height[c] + 1 : 0;
        }

        // 單調遞增棧找最大矩形
        top = 0;
        for (int c = 0; c <= COLS; c++) {
            int h = (c == COLS) ? 0 : height[c];
            while (top > 0 && h < height[stack[top - 1]]) {
                int hh = height[stack[--top]];
                int left = (top == 0) ? 0 : stack[top - 1] + 1;
                int right = c - 1;
                int area = hh * (right - left + 1);
                if (area > 0) { // 找到非零矩形
                    *out_r1 = r - hh + 1;
                    *out_c1 = left;
                    *out_r2 = r;
                    *out_c2 = right;
                    return true;
                }
            }
            stack[top++] = c;
        }
    }
    return false;
}

算法三:前綴和 + 任意矩形 O(1) 查詢 —— O(R²C) = 2×10⁵ (工程實用)

預計算 2D 前綴和 sum[r][c] = (0,0) 到 (r,c) 的 * 總數。任意矩形 * 數 = sum[r2][c2] - sum[r1-1][c2] - sum[r2][c1-1] + sum[r1-1][c1-1]。若等於面積則為全 * 矩形。


int sum[ROWS+1][COLS+1] = {0};
for (int r = 1; r <= ROWS; r++)
  for (int c = 1; c <= COLS; c++)
    sum[r][c] = sum[r-1][c] + sum[r][c-1] - sum[r-1][c-1] + (img[r-1][c-1] == '*');

for (int r1 = 1; r1 <= ROWS; r1++)
  for (int c1 = 1; c1 <= COLS; c1++)
    for (int r2 = r1; r2 <= ROWS; r2++)
      for (int c2 = c1; c2 <= COLS; c2++) {
        int stars = sum[r2][c2] - sum[r1-1][c2] - sum[r2][c1-1] + sum[r1-1][c1-1];
        int area = (r2 - r1 + 1) * (c2 - c1 + 1);
        if (stars == area) return true;
      }

讀取輸入的關鍵細節


// 逐字符讀取,跳過行尾換行
for (int r = 0; r < ROWS; r++) {
    for (int c = 0; c < COLS; c++) {
        int ch = getchar();
        while (ch == '\n' || ch == '\r') ch = getchar(); // 吞掉換行
        img[r][c] = (char)ch;
    }
}

複雜度對比與選型建議

算法時間複雜度空間複雜度實現難度推薦場景
暴力枚舉O(R²C²)O(1)低教學/極小矩陣
前綴和枚舉O(R²C)O(RC)中R,C ≤ 200 通用
直方圖+單調棧O(RC)O(C)高大矩陣/線上判斷/找最大矩形

結語

字符矩陣矩形檢測是 2D 模式識別的入門問題。從暴力枚舉到直方圖單調棧,複雜度優化路徑清晰展示了「預計算 + 資料結構」的算法威力。C 語言的陣列佈局與指標運算極適合實現這類演算法,掌握前綴和、單調棧兩大通用技術,能解決從圖像處理、表格分析到遊戲地圖檢測的廣泛問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved