找出给定字符串中的所有的连续递增和连续递减的子字符串

找出给定字符串中的所有的连续递增和连续递减的子字符串。子字符串长度至少是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);

最后

代码是笔试完之后,花了快一个小时才撸出来的,太笨了,哈哈。
看起来有点丑,不过我觉得这样写比较容易理解,算法复杂度应该也没啥问题,毕竟只遍历了一次。
那就先这样了,感谢阅读~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。