Rumah >pembangunan bahagian belakang >tutorial php >恶搞 关于腾讯的那道题截取字符串的题
题目是: 123 123 P4+768MB 机运行速度如下 欢迎各位 PHP 爱好者来 QQ群:23930992 程序处理一些特殊数据的时候会出问题,请把代码粘贴到上面 又修正一个错误,请把下面代码粘贴到上面
假设有"123abc456def789"这么一个字符串,写一个函数,可以传入一个字符串,和一个要截取的长度。返回截取后的结果。
要求:
1 和标记不得计算在长度之内。
2 截取后的字符串,要保留原有标签,不过如果最后有一个标签没有闭合,则去掉其开始标签。
示例:
题中的字符串,要截取长度5,则返回的字符串应该为:123ab,要截取长度8,应返回123abc45。
<?php// QQ群:23930992function find($str, $size, &$string, &$number, &$saveString, &$newString) // 查找标签,当 PHP > 5.3 可以把注释去掉{ $i=$j=0; while(strlen($saveString)<$size) { //loop: if($str[$i] == '<') { $k=0; $number[$j][$k++]=$i; $string[$j]=''; do { $string[$j].=$str[$i]; if($str[$i] == '>') { $number[$j++][$k++]=$i; break; } }while($str[$i++] != '>'); } else { $saveString.=$str[$i]; /*if(strlen($saveString) == $size) { if($str[++$i] =='<') { goto loop; } $i--; }*/ } $i++; } for($j=0; $j<$i; $j++) { $newString.=$str[$j]; }}function filter($str) // 过滤标签,然后进行比较{ $newstr = ''; $strLength = strlen($str); for($i=0;$i<$strLength;$i++) { switch($str[$i]) { case '<' : continue; case '/' : continue; case '>' : continue; case ' ' : break; default : $newstr .= $str[$i]; } } return $newstr;}function deleteReservedTag(&$string, &$number, $reserved) // 从标签组里去除 保留标签{ $stringLength = count($string); $reservedLength = count($reserved); for($i=0; $i<$stringLength;$i++) // 去掉保留标签部分 { for($j=0;$j < $reservedLength;$j++) { if( filter($string[$i]) == filter($reserved[$j]) ) { $string[$i] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = NULL; } } } } $tempString[] = ''; $tempNumber[][] = 0; for($i=0,$j=0; $i < $stringLength; $i++) // 把空的地方填补 { if($string[$i] != NULL) { $tempString[$j]=$string[$i]; for($k=0;$k<2;$k++) { $tempNumber[$j][$k] = $number[$i][$k]; } $j++; } } $string = $tempString; $number = $tempNumber;}function compare(&$string, &$number) //比较成对标签{ $stringLength = count($string); for($i=0; $i < $stringLength; $i++) //删除成对标签 { for($j = $i+1; $j < $stringLength; $j++) { if( filter($string[$i]) == filter($string[$j]) ) { $string[$i] = NULL; $string[$j] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = NULL; } for($k=0;$k<2;$k++) { $number[$j][$k] = NULL; } } } } $tempString[] = ''; $tempNumber[][] = 0; for($i=0,$j=0; $i < $stringLength; $i++) // 把空的地方填补 { if($string[$i] != NULL) { $tempString[$j]=$string[$i]; for($k=0;$k<2;$k++) { $tempNumber[$j][$k] = $number[$i][$k]; } $j++; } } $string = $tempString; $number = $tempNumber;}function replace(&$string, $number, $newString){ $tempString = ''; $saveStringLength = strlen($newString); $stringLength = count($string); //echo $saveStringLength."\n".$stringLength; for($i=0, $j=0; $i < $saveStringLength; $i++) { if( $j < $stringLength ) { if( $i == $number[$j][0]) { $begin = $number[$j][1] - $number[$j][0]; while($begin) { $begin--; $i++; } $j++; $i++; } } $tempString .= $newString[$i]; } $string = $tempString;}$str = '<p align="center"><b>123<br /><em>abc</em>45<hr />6</b>defg<i>789</i></p>';$size=15;$reserved = array //保留标签( '<br />', '<br>', '<hr />', '<hr>');$string[]=''; // 保存所有标签$number[][]=0; // 保存所有标签位置$saveString = ''; // 保存截取标签后的所有字符串$newString = ''; // 保存所有未截取标签的字符串find($str, $size, $string, $number, $saveString, $newString); // 查找标签deleteReservedTag($string, $number, $reserved); // 从标签组里去除 保留标签compare($string, $number); // 从标签组里去除 成对标签replace($string, $number, $newString);printf("截取长度:%d\n\n", $size);printf("完整长度:%s\n\n",$str);printf("处理结果:%s\n\n", $string);printf("截取长度:%s (%s)\n\n",$saveString,strlen($saveString));printf("未处理前:%s\n",$newString);?>
运算结果如下
------------------------------------------------------------------------------------
截取长度:15
完整长度:
abc45
6defg789
处理结果:123
abc45
6defg78
截取长度:123abc456defg78 (15)
未处理前:
abc45
6defg78
回复讨论(解决方案)
内存使用情况:2176
算法运行时间(microtime):0.0012378692626953
function filter($str) // 过滤标签,然后进行比较
{
$newstr = '';
$strLength = strlen($str);
for($i=0;$i {
switch($str[$i])
{
case ' case '/' : continue;
case '>' : continue;
case ' ' : break 2;
default : $newstr .= $str[$i];
}
}
return $newstr;
}
function replace(&$string, $number, $newString){ $tempString = ''; $saveStringLength = strlen($newString); $stringLength = count($string); for($i=0, $j=0; $i < $saveStringLength; $i++) { if( $j < $stringLength ) { if( $i == $number[$j][0]) { $begin = $number[$j][1] - $number[$j][0]; while($begin) { $begin--; $i++; } $j++; } } else { $tempString .= $newString[$i]; } } $string = $tempString;}
完整修改后的代码
<?php// QQ群:23930992function find($str, $size, &$string, &$number, &$saveString, &$newString) // 查找标签,当 PHP > 5.3 可以把注释去掉{ $i=$j=0; while(strlen($saveString)<$size) { //loop: if($str[$i] == '<') { $k=0; $number[$j][$k++]=$i; $string[$j]=''; do { $string[$j].=$str[$i]; if($str[$i] == '>') { $number[$j++][$k++]=$i; break; } }while($str[$i++] != '>'); } else { $saveString.=$str[$i]; /*if(strlen($saveString) == $size) { if($str[++$i] =='<') { goto loop; } $i--; }*/ } $i++; } for($j=0; $j<$i; $j++) { $newString.=$str[$j]; }}function filter($str) // 过滤标签,然后进行比较{ $newstr = ''; $strLength = strlen($str); for($i=0;$i<$strLength;$i++) { switch($str[$i]) { case '<' : continue; case '/' : continue; case '>' : continue; case ' ' : break 2; default : $newstr .= $str[$i]; } } return $newstr;}function deleteReservedTag(&$string, &$number, $reserved) // 从标签组里去除 保留标签{ $stringLength = count($string); $reservedLength = count($reserved); for($i=0; $i<$stringLength;$i++) // 去掉保留标签部分 { for($j=0;$j < $reservedLength;$j++) { if( filter($string[$i]) == filter($reserved[$j]) ) { $string[$i] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = NULL; } } } } $tempString[] = ''; $tempNumber[][] = 0; for($i=0,$j=0; $i < $stringLength; $i++) // 把空的地方填补 { if($string[$i] != NULL) { $tempString[$j]=$string[$i]; for($k=0;$k<2;$k++) { $tempNumber[$j][$k] = $number[$i][$k]; } $j++; } } $string = $tempString; $number = $tempNumber;}function compare(&$string, &$number) //比较成对标签{ $stringLength = count($string); for($i=0; $i < $stringLength; $i++) //删除成对标签 { for($j = $i+1; $j < $stringLength; $j++) { if( filter($string[$i]) == filter($string[$j]) ) { $string[$i] = NULL; $string[$j] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = NULL; } for($k=0;$k<2;$k++) { $number[$j][$k] = NULL; } } } } $tempString[] = ''; $tempNumber[][] = 0; for($i=0,$j=0; $i < $stringLength; $i++) // 把空的地方填补 { if($string[$i] != NULL) { $tempString[$j]=$string[$i]; for($k=0;$k<2;$k++) { $tempNumber[$j][$k] = $number[$i][$k]; } $j++; } } $string = $tempString; $number = $tempNumber;}function replace(&$string, $number, $newString){ $tempString = ''; $saveStringLength = strlen($newString); $stringLength = count($string); for($i=0, $j=0; $i < $saveStringLength; $i++, $j=0) { while( $j < $stringLength ) { if( $i == $number[$j][0]) { $i = $number[$j][1]; $i++; } $j++; } $tempString .= $newString[$i]; } $string = $tempString;}$sttime = microtime(true);$stmem = memory_get_usage();$str = ' <table id="ctl00_ContentPlaceHolder1_BidDomainName1_Shop1_htmlShop" width="99%" border="0" cellspacing="0" cellpadding="0"> <tr> <td valign="top"><img id="ctl00_ContentPlaceHolder1_BidDomainName1_Shop1_imgShopLogo" src="http://auction.ename.cn/images/nopic.gif" style="max-width:90%" / alt="恶搞 关于腾讯的那道题截取字符串的题" ></td> <td><h5>364867的玉米小店</h5> 买家信用:<a id="ctl00_ContentPlaceHolder1_BidDomainName1_Shop1_hlBuyerCreditLink" title="0" href="/Customer/UserEvaluate.aspx?uid=364867&from=seller" target="_blank">0<span class="goodssaletitle2"></span></a><br /> 卖家好评率:100.00%<br /> 买家好评率:0.00%<br /> 注册时间:2010年04月29日<br /> <div style="width:230px">荣誉资质:<img alt="恶搞 关于腾讯的那道题截取字符串的题" ></div> <div><a id="ctl00_ContentPlaceHolder1_BidDomainName1_Shop1_hlShopUrl" href="http://364867.shop.ename.cn"><img src="/images/scicon.gif" style="max-width:90%" style="max-width:90%" border="0" / alt="恶搞 关于腾讯的那道题截取字符串的题" ></a></div></td> </tr></table> </td> </tr> <tr> <td class="shopbg04"> </td> </tr> </table>';$size=160;$reserved = array //保留标签( '<br />', '<br>', '<hr />', '<hr>', '<img / alt="恶搞 关于腾讯的那道题截取字符串的题" >', '<img alt="恶搞 关于腾讯的那道题截取字符串的题" >');$string[]=''; // 保存所有标签$number[][]=0; // 保存所有标签位置$saveString = ''; // 保存截取标签后的所有字符串$newString = ''; // 保存所有未截取标签的字符串find($str, $size, $string, $number, $saveString, $newString); // 查找标签deleteReservedTag($string, $number, $reserved); // 从标签组里去除 保留标签compare($string, $number); // 从标签组里去除 成对标签replace($string, $number, $newString);printf("截取长度:%d\n\n", $size);printf("完整长度:%s\n\n",$str);printf("处理结果:%s\n\n", $string);printf("截取长度:%s (%s)\n\n",$saveString,strlen($saveString));printf("未处理前:%s\n",$newString);echo "内存使用情况:",(memory_get_usage()-$stmem),"\n";echo "算法运行时间(microtime):",(microtime(true)-$sttime),"\n";?>
364867的玉米小店买家信用:0 卖家好评率:100.00% 买家好评率:0.00% 注册时间:2010年04月29日 荣誉资质:
|
364867的玉米小店买家信用:0 卖家好评率:100.00% 买家好评率:0.00% 注册 内存使用情况:5096 算法运行时间(microtime):0.0040628910064697 精简后的代码 <?php// QQ群:23930992function find($str, $size, &$string, &$number, &$saveString, &$newString) // 查找标签并保存到标签组{ $i=$j=0; while(strlen($saveString)<$size) { if($str[$i] == '<') { $k=0; $number[$j][$k++]=$i; $string[$j]=''; do { $string[$j].=$str[$i]; $i++; }while($str[$i] != '>'); $number[$j++][$k]=$i; } else { $saveString.=$str[$i]; } $i++; } for($j=0; $j<$i; $j++) { $newString.=$str[$j]; }}function filter($str) // 过滤标签,然后进行比较{ $newstr = ''; $strLength = strlen($str); for($i=0;$i<$strLength;$i++) { switch($str[$i]) { case '<' : continue; case '/' : continue; case '>' : continue; case ' ' : break 2; default : $newstr .= $str[$i]; } } return $newstr;}function deleteReservedTag(&$string, &$number, $reserved) // 从标签组里去除 保留标签{ $stringLength = count($string); $reservedLength = count($reserved); for($i=0; $i<$stringLength;$i++) // 去掉保留标签部分 { for($j=0;$j < $reservedLength;$j++) { if( filter($string[$i]) == filter($reserved[$j]) ) { $string[$i] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = NULL; } } } }}function compare(&$string, &$number) //比较成对标签{ $stringLength = count($string); for($i=0; $i < $stringLength; $i++) //删除成对标签 { for($j = $i+1; $j < $stringLength; $j++) { if( filter($string[$i]) == filter($string[$j]) ) { $string[$i] = $string[$j] = NULL; for($k=0;$k<2;$k++) { $number[$i][$k] = $number[$j][$k] = NULL; } } } } //begin 把标签组空的地方 填补 (你可以去除本小段代码,代价是运行时间增加了) $tempString[] = ''; $tempNumber[][] = 0; for($i=0,$j=0; $i < $stringLength; $i++) { if($string[$i] != NULL) { $tempString[$j]=$string[$i]; for($k=0;$k<2;$k++) { $tempNumber[$j][$k] = $number[$i][$k]; } $j++; } } $string = $tempString; $number = $tempNumber; //end}function replace(&$string, $number, $newString) // 核心代码 ...{ $tempString = ''; $saveStringLength = strlen($newString); $stringLength = count($string); for($i=0, $j=0; $i < $saveStringLength; $i++, $j=0) { while( $j < $stringLength ) { if( $i == $number[$j][0]) { $i = $number[$j][1]; $i++; } $j++; } $tempString .= $newString[$i]; } $string = $tempString;}$sttime = microtime(true);$stmem = memory_get_usage();$str = '<p align="center"><b>123<br /><em>abc</em>45<hr />6</b>d<strong>efg<i>789</i></strong></p>';$size=15;$reserved = array //保留标签( '<br />', '<br>', '<hr />', '<hr>', '<img / alt="恶搞 关于腾讯的那道题截取字符串的题" >', '<img alt="恶搞 关于腾讯的那道题截取字符串的题" >');$string[]=''; // 保存所有标签$number[][]=0; // 保存所有标签位置$saveString = ''; // 保存截取标签后的所有字符串$newString = ''; // 保存所有未截取标签的字符串find($str, $size, $string, $number, $saveString, $newString); // 查找标签deleteReservedTag($string, $number, $reserved); // 从标签组里去除 保留标签compare($string, $number); // 从标签组里去除 成对标签//deleteSpaceArray($string, $number); // 删除标签组里空下来的空间//deleteSpaceArray($string, $number); // 删除标签组里空下来的空间replace($string, $number, $newString);printf("截取长度: %u\n\n", $size);printf("完整长度: %s\n\n", $str);printf("截取长度: %s (%u)\n\n", $saveString, strlen($saveString));printf("处理结果: %s\n\n", $string);printf("未处理前: %s\n\n", $newString);printf("内存使用情况:%u\n", memory_get_usage()-$stmem);printf("算法运行时间(microtime): %f\n", microtime(true)-$sttime);?> 研究得好透彻啊 人都去那了啊,郁闷了
$s = '123<em>abc</em>456<em>def</em>789<em>def</em>789<em>def</em>789<em>def</em>789';function subs($s, $len){//此函数参数有二:$s - 源字符串, $len - 要截取的长度 (当让你也可以将标签传进来,不过要进行其他操作) $s1 = $s; $s1 = preg_replace('/<\/?em>/s', '', $s1); $sub = mb_substr($s1, 0, $len, 'gbk'); //处理成数组 $s2 = $s; $s2 = preg_replace('/<\/?em>/s', '[p]', $s2); $arr = explode('[p]', $s2); $arr1 = $arr2 = array(); $num = count($arr); $num1 = $num2 = 0; $bs = 0; for($i = 0; $i < $num; $i++){ $arr1[] = strlen($arr[$i]); $num2 = array_sum($arr1); if($num2 >= $len){ $num1 = $len - $num2 + strlen($arr[$i]); if($num1 != strlen($arr[$i]))$bs = 1 $s3 = mb_substr($arr[$i], 0, $num1, 'gbk'); $arr[$i] = $s3; $arr2 = array_slice($arr, 0, $i + 1); break; } } //处理数组,结合成所需要的成字符串 $num = count($arr2); $s4 = ''; for($i = 0; $i < $num; $i++){ if($i % 2 == 0){ if(($i + 1 == $num && $bs == 1) || ($i + 2 == $num && $bs == 1) || ($num % 2 == 1 && $i + 1 == $num)){ $s4 .= $arr2[$i]; }else{ $s4 .= $arr2[$i]."<em>"; } }else{ if($i + 1 == $num && $bs == 1){ $s4 .= $arr2[$i]; }else{ $s4 .= $arr2[$i]."</em>"; } } } //返回结果 return $s4;}$s = subs($s, 17);echo $s; 支持盗版!!! |