还是腾讯的一道题

题目是:
假设有"123<em>abc</em>456<em>def</em>789"这么一个字符串,写一个函数,可以传入一个字符串,和一个要截取的长度。返回截取后的结果。

要求:
1 <em>和</em>标记不得计算在长度之内。
2 截取后的字符串,要保留原有<em>标签,不过如果最后有一个标签没有闭合,则去掉其开始标签。

示例:
题中的字符串,要截取长度5,则返回的字符串应该为:123ab,要截取长度8,应返回123<em>abc</em>45。

 

 

我的做法大概思路是:
1 首先顺序读取字符串,并用一个resultstr变量来记录所有字符,当发现<标记时,开始将这个子字符串用tag变量记录下来。
2 如果发现tag变量形式为</w+>也就是html标签的开始标记),就将其入栈。用栈结构来存储这个标记。若遇到<///w+>(html标签的结束标记),就出栈。

3 否则如果是常规字符的话,长度计数器++。直到与传入的要截取长度相等。

4 最后判断栈是否为空,如果为空,直接返回截取后的字符串,否则,将栈中剩余元素一个个出栈,循环从截取后的字符串中查找栈顶标签元素最后一次出现的位置,返回索引,将这个标签替换为空。直到整个栈为空为止。最后返回处理后的字符串。

 

 

 

 

 

 

 

 

<?php
function mySubstr( $str, $length ){


   
$tag = '';
   
$resultstr = '';
   
$tagstack = array();

   
for( $i = 0; $i < $length; $i++ ){
       
if( $str[$i] == '<' ){

           
$resultstr .= $str[$i];

           
for( $j=$i; $str[$j]!='>'; $j++,$length++ ){
               
$tag .= $str[$j];
            }


           
$length++;
           
$tag .= '>';
           
           
//如果是开始标记,则入栈,如果是与之相对应的结束标记则出栈
            if( preg_match('/<([^//]+)?>/i', $tag, $r) ){
               
echo '入栈:',htmlspecialchars($r[1]),'<br />';
               
array_push($tagstack, $r[1]);elseif( preg_match( '/'.$tagstack[count($tagstack)-1].'/', $tag ) ){
               
echo '出栈:',htmlspecialchars($tagstack[count($tagstack)-1]),'<br />';
               
array_pop( $tagstack ); } $tag = '';
           
continue;
        }

       
$resultstr .= $str[$i];
    }

   
   
echo '<hr size=1>最后结果为:';

   
//栈是空的直接返回
    if(empty($tagstack)){
       
return $resultstr;
    }
   
//否则去掉没有结束标记的开始标记
    else{
       
       
while(!empty($tagstack)){

           
$tag = array_pop($tagstack);

           
$index = strrpos($resultstr, $tag);

           
for($i = $index-1; $resultstr[$i] != '>'; $i++ ){
               
$resultstr[$i] = '';
            }

           
$resultstr[$i++] = '';
       
        }

       
return $resultstr;
    }
   
}

$sttime = microtime(true);

$stmem = memory_get_usage();

$str = "a1<body>b2<p>c3<em>d4</em>e5</p>f6</body>g7h8";

echo '处理结果为:<br/><hr size=1>',htmlspecialchars( mySubstr( $str, 18 ) ),'<br />';

echo "内存使用情况:",(memory_get_usage()-$stmem),'<br />';

echo "算法运行时间(microtime):",(microtime(true)-$sttime),'<br/>';

}

 

?>


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值