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

C#矩阵环形区域元素搜索算法实现求助

解决方案:C#矩阵环形区域元素提取

核心思路

要提取目标坐标周围的环形元素,本质是获取以目标为中心、半径为指定值的正方形环边缘。我们可以通过两种高效方式实现,同时全程做越界检查保证鲁棒性:

方法1:定向遍历四条边(高效)

环形由四条边组成:上边、下边、左边、右边。直接遍历这四条边的坐标,跳过矩阵外的无效点,收集有效元素:

  1. 计算环形的上下左右边界(基于目标坐标和半径)
  2. 分别遍历四条边,对每个坐标做矩阵范围校验,有效则加入结果列表
  3. 左右边需排除与上下边重复的端点,避免元素重复

方法2:范围遍历+条件判断(简洁)

先限定遍历范围在矩阵有效区域内,再判断每个点是否属于环形(通过切比雪夫距离:max(|行差|, |列差|) == radius),满足条件则收集元素。逻辑更直观,适合中小矩阵场景。


代码实现

方法1:定向遍历四条边

using System.Collections.Generic;

public static class MatrixHelper
{
    public static List<T> GetRingElements<T>(T[,] matrix, (int Row, int Col) target, int radius)
    {
        var ringElements = new List<T>();
        int totalRows = matrix.GetLength(0);
        int totalCols = matrix.GetLength(1);

        // 计算环形的四个边界
        int topEdge = target.Row - radius;
        int bottomEdge = target.Row + radius;
        int leftEdge = target.Col - radius;
        int rightEdge = target.Col + radius;

        // 遍历上边
        for (int col = leftEdge; col <= rightEdge; col++)
        {
            if (topEdge >= 0 && topEdge < totalRows && col >= 0 && col < totalCols)
            {
                ringElements.Add(matrix[topEdge, col]);
            }
        }

        // 遍历下边
        for (int col = leftEdge; col <= rightEdge; col++)
        {
            if (bottomEdge >= 0 && bottomEdge < totalRows && col >= 0 && col < totalCols)
            {
                ringElements.Add(matrix[bottomEdge, col]);
            }
        }

        // 遍历左边(跳过上下边已包含的端点)
        for (int row = topEdge + 1; row <= bottomEdge - 1; row++)
        {
            if (row >= 0 && row < totalRows && leftEdge >= 0 && leftEdge < totalCols)
            {
                ringElements.Add(matrix[row, leftEdge]);
            }
        }

        // 遍历右边(跳过上下边已包含的端点)
        for (int row = topEdge + 1; row <= bottomEdge - 1; row++)
        {
            if (row >= 0 && row < totalRows && rightEdge >= 0 && rightEdge < totalCols)
            {
                ringElements.Add(matrix[row, rightEdge]);
            }
        }

        return ringElements;
    }
}

方法2:范围遍历+条件判断

using System.Collections.Generic;
using System;

public static class MatrixHelper
{
    public static List<T> GetRingElementsAlt<T>(T[,] matrix, (int Row, int Col) target, int radius)
    {
        var ringElements = new List<T>();
        int totalRows = matrix.GetLength(0);
        int totalCols = matrix.GetLength(1);

        // 限定遍历范围在矩阵有效边界内,避免无效遍历
        int startRow = Math.Max(0, target.Row - radius);
        int endRow = Math.Min(totalRows - 1, target.Row + radius);
        int startCol = Math.Max(0, target.Col - radius);
        int endCol = Math.Min(totalCols - 1, target.Col + radius);

        for (int row = startRow; row <= endRow; row++)
        {
            for (int col = startCol; col <= endCol; col++)
            {
                // 判断当前点是否在环形上(切比雪夫距离等于半径)
                if (Math.Max(Math.Abs(row - target.Row), Math.Abs(col - target.Col)) == radius)
                {
                    ringElements.Add(matrix[row, col]);
                }
            }
        }

        return ringElements;
    }
}

测试示例

以9x9矩阵、目标坐标(4,5)、半径3为例:

// 初始化矩阵,赋值为行号*10+列号
int[,] testMatrix = new int[9, 9];
for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        testMatrix[i, j] = i * 10 + j;
    }
}

// 提取环形元素
var target = (Row: 4, Col: 5);
var result = MatrixHelper.GetRingElements(testMatrix, target, 3);

// 输出结果将包含:12,13,14,15,16,17,18,72,73,74,75,76,77,78,22,32,42,52,62,28,38,48,58,68

鲁棒性说明

两种方法都做了严格的越界校验:

  • 方法1直接对每个坐标判断是否在矩阵的[0, 总行数-1]和[0, 总列数-1]范围内
  • 方法2先通过Math.Max/Min限定遍历范围,避免访问矩阵外的区域

即使目标坐标靠近矩阵边缘、半径过大导致环形超出矩阵范围,也能安全返回有效元素,不会抛出越界异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:40:36