tom.com php面试题

时间:2009-10-10     作者:smarteng     分类: PHP相关


都不算太难,应该说很简单就过了。

拿其中一道题说说吧

题目要求大体是这样的:

给一个字符串 $s = 'Welcome to tom!',要他把这个字符串里面的每个单词翻转,
注意不是从头到尾翻转,而是把每个单词翻转,应该输出为:

$s='emocleW ot !mot';不能用php自带的函数,

当时还有两个题,要求在一定时间内完成,写的不好,现在来重新写一下,

开始用的递归,后来想想,太浪费了,其实很简单(受徐哥启发)

下面是给出的完整代码:[break]

/**
 * @Fun:把一个串中的单词翻转
 *
 * @param string &$word 想翻转的字符串,直接来操作所给的字符串
 * @param int $start 串中单词开始的位置
 * @param int $end 串中单词结束的位置
 * @return void
 * @author smarteng <smarteng@yeah.net>
 */
function reverse(&$word,$start,$end)
{
 $len=$end-$start+1;
 $mid= ceil( $len/2 );

 for($i=0;$i<$mid;$i++)
 {
  $tmp=$word[$start+$i];
  $word[$start+$i]=$word[$end-$i];
  $word[$end-$i]=$tmp;
 }
}

 

function resortString(&$word){
 $len = strlen($word);
 
 for($i=0;$i<$len;$i++)
 {
  
  //welcome to tom
  //第一个非空白字符
  while($i<$len && $word[$i]==' ') $i++;
  //获得单词开始的位置
  $start_pos = $i;
  
  while($i<$len && $word[$i]!=' ') $i++;
        //获得单词结束的位置
  $end_pos=$i-1;
  
  reverse($word,$start_pos,$end_pos);
  
 }

}

$s = ‘Welcome to      the   Real World !’;

resortString($s);
echo $s;

————————今天看到一个更猛的——————————

分析
主要是字符串定位,提取和反转,用正则是最应该先想到的方向

代码
<?php
$str = '[];/hello../,world/frds';
$pattern = '/([a-z0-9]+)/ie';
$replacement = 'strrev("
\\1")';
 
echo preg_replace($pattern, $replacement, $str);
补充
这是我在看了其他人的解法之后另外想的一个,这种情况下思路就被别人的方法束缚了,所以弄个差不多的出来,算是让大家重新熟悉一下这种语法吧。主要是e修正符的使用。

 原文地址:http://vipzhicheng.com/node/169

 另一个是返回Key 的

<?
$array=array(2,3,1,5,-1,4);

function returnKey($a)
{
 $number = count($a);
 $pos=0;
 while($a[$pos]!=-1)
 {
  $tmp=$pos;
  if($a[$pos]==-2) return -1;
  $pos=$a[$pos];
  $a[$tmp]=-2;
  if($pos > $number) return -1;
 }
 return $pos;
}

echo returnKey($array);
?>

 

还有一个求中间值的:

<?
$array=array(2,3,1,5,-1,4);

function returnKey($a)
{
 $number = count($a);
 $pos=0;
 while($a[$pos]!=-1)
 {
  $tmp=$pos;
  if($a[$pos]==-2) return -1;
  $pos=$a[$pos];
  $a[$tmp]=-2;
  if($pos > $number) return -1;
 }
 return $pos;
}

echo returnKey($array);

//之后做相应的处理

 

查找中间位置:
当然可以用二分查找,使查找的更迅速,我只是简单的实现了,也可以像徐哥那样

        1   2   3   4   5   ....  100
       ==============================
Lsum    1   3   6   10  15  ....   5050
Rsum    5050                   199 100
 

先遍历一下,做好两个数字 ,之后比对,对多次查询,是一个灰常不错的方法~

<?
$a=array(1,1,1,1,1,1,1,13,7);

function findmiddle($a)
{
 $number =count($a);
 $leftsum = $a[0];
 $rightsum = array_sum($a)-$a[0]-$a[1];
 for ($i = 1;$i <$number;$i++) {
//  echo " start for: leftsum=$leftsum ,rithtsum= '$rightsum' <br>";
  if($leftsum != $rightsum){
   $leftsum += $a[$i];
   $rightsum -= $a[$i+1];
//   echo " leftsum=$leftsum ,rithtsum= '$rightsum' <br>";
  }else if($leftsum == $rightsum){
   return $a[$i];
  }else {
   return -1;//没找到
  }
 }
 
}
$theNumber = findmiddle($a);
echo $theNumber;
?>