PHP高效判断字符串数组是否含月份三字母缩写的最优方法
更高效的月份缩写检测方案
嘿,你的嵌套循环不仅效率不高,还存在逻辑问题(同一个元素会因为不同月份多次输出结果),我来给你几个更优的解决方案,既高效又简洁:
问题分析
原代码的时间复杂度是O(n*m)(n是月份数,m是目标数组长度),而且会对同一个元素重复判断12次,导致输出冗余。我们需要把逻辑改成每个元素只判断一次是否包含任意一个月份缩写,同时降低时间复杂度。
方案一:正则表达式(推荐)
利用正则的备选组特性,一次性匹配所有月份缩写,只需要遍历目标数组一次即可完成所有判断:
$array = array( 'AUS200JAN', 'GOLD300MAR', 'AUS200_h18', 'GOLD300_g19', 'EURUSDJUL18', 'AUSEURNOV18' ); $monthAbbrs = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; // 构建正则模式:匹配任意一个月份缩写,如需不区分大小写可添加`i`修饰符 $monthPattern = '/(' . implode('|', $monthAbbrs) . ')/'; // 逐个判断元素 foreach ($array as $item) { if (preg_match($monthPattern, $item)) { echo "* $item 包含月份缩写\n"; } else { echo "* $item 不包含月份缩写\n"; } } // 如果只需要筛选出包含月份的元素,直接用preg_grep更高效 $filteredItems = preg_grep($monthPattern, $array); echo "\n筛选出的含月份元素:\n"; print_r($filteredItems);
这个方案的时间复杂度是O(m)(m为目标数组长度),正则引擎的匹配效率非常高,尤其适合处理大规模数组。
方案二:利用数组函数优化遍历
如果你不想用正则,可以提前把月份缩写转为查找集合,然后用自定义函数来判断每个元素是否匹配:
$array = array( 'AUS200JAN', 'GOLD300MAR', 'AUS200_h18', 'GOLD300_g19', 'EURUSDJUL18', 'AUSEURNOV18' ); $monthAbbrs = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC']; // 自定义判断函数:检查元素是否包含任意月份缩写 function hasMonthAbbr($item, $monthList) { foreach ($monthList as $abbr) { if (strpos($item, $abbr) !== false) { return true; } } return false; } // 遍历处理 foreach ($array as $item) { $result = hasMonthAbbr($item, $monthAbbrs) ? "包含" : "不包含"; echo "* $item $result 月份缩写\n"; }
这个方案的时间复杂度是O(m*k)(k是匹配到月份的平均次数),但比原嵌套循环好,因为一旦找到匹配的月份就会终止当前元素的判断,不会遍历所有12个月份。
原代码的逻辑修正
顺便提一下,你的原代码会对同一个元素输出12次结果(每个月份一次),这显然不符合需求。如果要保留嵌套循环的思路,至少要改成找到匹配就跳出循环:
$array = array( 'AUS200JAN', 'GOLD300MAR', 'AUS200_h18', 'GOLD300_g19', 'EURUSDJUL18', 'AUSEURNOV18' ); $montharray = array( 'JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC' ); foreach($array as $val) { $hasMonth = false; foreach($montharray as $month) { if(strpos($val,$month)!== FALSE) { $hasMonth = true; break; // 找到匹配就终止内层循环 } } var_dump($hasMonth ? 'has month' : 'Does not contain month'); }
但这个方案还是不如前面的正则或优化后的数组函数高效。
内容的提问来源于stack exchange,提问作者ShanjayG
相关产品推荐
相关产品推荐

