找出给定字符串中的所有的连续递增和连续递减的子字符串。子字符串长度至少是2。
举例1输入“abcxd321"输出“abc",“321"。说明:其中“abc”是连续递增的字符串,“321”是连续递减。
举例2输入“abcdc”输出“abcd”。
说明:子字符串不重叠,字符优先匹配到前面的递增或递减序列里。
这是我面试的一家公司的笔试题,要求30分钟内作答完毕,我没做完。。。故记录下
思路
遍历字符串,从前至后依次比较每个字符的大小(使用ord函数比较ASCII码)
用变量保存连续子串的开始的位置(偏移量),当然发现不满足连续条件时,输出子串,并重置起始的偏移量
代码
<?php
$str = 'abcxd321';
//输出符合条件的字串并重置相关变量
function reset_echo($str)
{
if (isset($GLOBALS['start'])) {
//输出符合条件的子串
echo substr($str, $GLOBALS['start'], $GLOBALS['k']+1), "\r\n";
}
//重置 $flag和 $start
unset($GLOBALS['flag']);
unset($GLOBALS['start']);
}
//遍历字符串
for ($k=0; $k<strlen($str)-1; $k++) {
//获取当前字符和下一个字符的ASCII码,用于比较
$now = ord($str[$k]);
$next = ord($str[$k+1]);
//下一个字符与当前字符的差是 1或-1时,说明字符串时递增或递减
if (in_array($next - $now , [-1,1])) {
//定义标志位 $flag 1 代表递增 -1 代表递减
if (!isset($flag)) {
$flag = $next - $now;
}
//定义连续的子串的起始位 $start
if (!isset($start)) {
$start = $k;
}
//当下个字符与当前字符的差 不等于 标志位 ,说明递增或递减的形态已经发生了变化
if ($next - $now != $flag) {
reset_echo($str);
}
} else {
//当下个字符与当前字符的差 不等于 1 或 -1 说明根本不是递增或递减
//输出符合条件的字串,并重置$flag 和 $start
reset_echo($str);
}
}
//字符串遍历结束了,输出符合条件的字串
reset_echo($str);
最后
代码是笔试完之后,花了快一个小时才撸出来的,太笨了,哈哈。
看起来有点丑,不过我觉得这样写比较容易理解,算法复杂度应该也没啥问题,毕竟只遍历了一次。
那就先这样了,感谢阅读~