如何在NxN矩阵中检测水平、垂直、斜向的4个相同连续字母序列?
问题描述
现有如下NxN矩阵:
需要开发一个函数,接收如下格式的数组参数:
$dna = array("ATGCGA", "CAGTGC", "TTATGT", "AGAAGG", "CCCCTA", "TCACTG");
要求遍历矩阵,找出所有4个相同且连续排列的字母的匹配项,包含水平、垂直、斜向三种方向。目前已经实现了水平方向的检测功能,现有代码如下:
<?php $dna = array( array("A", "T", "G", "C", "G", "A"), array("C", "A", "G", "T", "G", "C"), array("T", "T", "A", "T", "G", "T"), array("A", "G", "A", "A", "G", "G"), array("C", "C", "C", "C", "T", "A"), array("T", "C", "A", "C", "T", "G"), ); function check($dna) { $fu = 0; foreach ($dna as $x) { for ($i = 0, $j = 1; $i < count($x); $i++, $j++) { if ($j < count($x)) { if ($x[$i] == $x[$j]) $fu++; } } if ($fu >= 4) { echo "equal<br>"; $fu = 0; } else echo "different<br>"; } } check($dna);
实现方案
你现有水平检测的逻辑存在小问题:4个连续相同的字符只会产生3次相邻相等的匹配,判断条件$fu >=4会漏判,需要先调整为$fu >=3。
要补充垂直和斜向检测,最简洁的方式是预先定义所有需要检查的方向增量,复用同一套检测逻辑,不需要写多套重复代码。完整实现代码如下:
<?php function checkDna($dna) { $n = count($dna); // 入参兼容:不管传入字符串数组还是拆分好的二维字符数组都可处理 $matrix = []; foreach ($dna as $row) { $matrix[] = is_array($row) ? $row : str_split($row); } // 四个方向增量:水平右、垂直下、右下斜、右上斜,覆盖所有连续排列场景 $directions = [[0, 1], [1, 0], [1, 1], [1, -1]]; $matchCount = 0; // 遍历所有单元格作为匹配起点 for ($i = 0; $i < $n; $i++) { for ($j = 0; $j < $n; $j++) { $currentChar = $matrix[$i][$j]; // 逐个方向校验 foreach ($directions as $dir) { $dx = $dir[0]; $dy = $dir[1]; // 提前判断沿当前方向走3步是否超出矩阵边界,过滤无效起点 $endX = $i + 3 * $dx; $endY = $j + 3 * $dy; if ($endX < 0 || $endX >= $n || $endY <0 || $endY >= $n) { continue; } // 检查连续4个字符是否完全相同 $isMatch = true; for ($k = 1; $k < 4; $k++) { if ($matrix[$i + $k*$dx][$j + $k*$dy] != $currentChar) { $isMatch = false; break; } } if ($isMatch) { $matchCount++; // 不需要统计重复匹配可以在这里break掉方向循环 } } } } // 可根据需求调整返回值:返回匹配总数,或者是否存在匹配 return $matchCount > 0; } // 测试用例 $dna = array("ATGCGA", "CAGTGC", "TTATGT", "AGAAGG", "CCCCTA", "TCACTG"); var_dump(checkDna($dna)); // 测试用例存在水平连续的CCCC,返回true
内容的提问来源于stack exchange,提问作者Rodrigo Ruiz
相关产品推荐
相关产品推荐

