利用PHP实现《剑指 offer》之字符串(数据结构与算法实战)

一定要认真看 分析 | 注释 | 题目要求

Question 1

题目描述:
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)

分析:
这是典型的动态规划问题 详见动态规划
第一种方法采用了状态转移方程(我也搞不太清楚)
第二种方法更为形象
代码如下:

<?php

function FindGreatestSumOfSubArray($array)
{
    // write code here
    if($array == null){
        return 0;
    }
    $max = $array[0];
    $res = $array[0];
    for($i=1;$i<count($array);$i++){
        $max = max($max+$array[$i],$array[$i]);
        $res = max($res,$max);
    }
    return $res;
}



/**
* Thinking: 
        假设第一个值为最大值,再初始化一个动态值(持续加的过程,值一直在变化),如果这个动态值为负数,则动态值重置为当前数值(因为当前数值无论是正是负再加上一个负值只会更小),反之则连加,再将动态值与最大值比较,将较大者赋给最大值。
*/
function FindGreatestSumOfSubArray($array)
{
    if(count($array) == 0 || $array == null){
        return 0;
    }
    $greateSum = $array[0];
    $curSum    = 0;

    $len = count($array);
    for($i = 0; $i < $len; $i++){
        if($curSum <= 0){
            $curSum = $array[$i];
        }
        else{
            $curSum += $array[$i];
        }
        if($curSum > $greateSum){
            $greateSum = $curSum;
        }
    }

    return $greateSum;
}

测试地址:https://www.nowcoder.com/prac...

Question 2

题目描述:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

分析:
利用哈希表 每个字符的ASCII码作为key

注1:哈希查找常常用于查找一个指定值相等的记录 而不需要比较
注2: 以下函数不为全排列(即不包括字符重复的情况)

代码如下:

<?php

/**
* @param $ar Array
* @param $k  int  出发序号
* @param $m  int  数组单元个数
*/
function perm(&$ar, $k=0, $m) {
    if($k == $m){ 
        echo join('',$ar), PHP_EOL;
    }else{
        for($i=$k; $i<=$m; $i++) {
            swap($ar[$k], $ar[$i]);
            perm($ar, $k+1, $m);
            swap($ar[$k], $ar[$i]);
        }
    }
}

function swap(&$a, &$b){
    $c = $a;
    $a = $b;
    $b = $c;
}

测试地址:https://www.nowcoder.com/prac...

Question 3

题目描述:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。

分析:
正则表达式

注:测试通过率不足100% 在此只提供一种思路

代码如下:

<?php

function isNumeric($s)
{
    // write code here
    $pattern = "/[\\+-]?[0-9]*(\\.[0-9]*)?([eE][\\+-]?[0-9]+)?/";
    return preg_match($pattern,$s);
}

测试地址:https://www.nowcoder.com/prac...

Question 4

题目描述:
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0

分析:
符号 数字
代码如下:

<?php

function StrToInt($str)
{
    // write code here
    $tem = array('1','2','3','4','5','6','7','8','9','0');  #预定义组成数字的元素数组
    $len = strlen($str);
    if($len == 0)return 0;
    $arr = str_split($str); #将字符串转换为数组

    $fuhao = 0;
    if($arr[0] == '-'){
        $fuhao = 1;
    }
    
    $sum = 0;
    for($i = $fuhao; $i<$len; $i++){
        if($arr[$i] == '+'){
            continue;
        }
        if(!in_array($arr[$i],$tem)){
            return 0;
        }
        $sum = $sum*10 + $arr[$i];
    }
    return $fuhao == 0 ? $sum : -1*$sum;
}

测试地址:https://www.nowcoder.com/prac...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值