当前位置:   article > 正文

经典面试题:玩家进游戏场地分配号码、判断括号是否闭合、提取回文串字符的分析和 php 程序实现 - 经典数据结构面试_php判断括号是否闭合

php判断括号是否闭合

经典面试题一、判断括号是否闭合的代码实现

1. 题目内容:

    给定一长串字母和符号,里面有三种括号包括([{}])这些,需要判断这三种括号必须是配对的。即这三类括号要么不出现,要出现必须是先出现左边的括号,然后出现右边的,中间括号可以嵌套。

2. 解答思路:

    定义一个字符对应关系数组,初始化一个数组栈。所以进入的左边符号入栈,如果进入的是右边的符号,则与栈中最后进入的元素进行配对判断,如果配对则消除这对符号。如果不配对,则说明不配对。

3. PHP编程实现:

  1. #([{)]}类括号符号是否闭合的判断
  2. #04.cn
  3. $args = getopt('c:');
  4. extract($args);
  5. echo "\n接收字符串:".$c."\n闭合判断结果:";
  6. function checkClose($str){
  7. #定义一个关系
  8. $relate = array('('=>')', '['=>']', '{'=>'}' );
  9. #遍历字符串将对应符号插入栈
  10. $quene = array();
  11. for($i=0; $i< strlen($str); $i++){
  12. #如果是出现了([{类字符,则直接存入栈等待配对
  13. if(isset($relate[$str{$i}])){
  14. array_push($quene, $str{$i});
  15. }elseif( in_array($str{$i}, $relate)){
  16. #如果出现了右边的)]}类字符,则必须与栈中最后一个元素相匹配,否则即为不是闭合的
  17. if($str{$i} != $relate[end($quene)]){
  18. return false;
  19. }else{
  20. #匹配的话则消除这对符号
  21. array_pop($quene);
  22. }
  23. }else{
  24. #非上述6个符号的内容不用考虑
  25. continue;
  26. }
  27. }
  28. #结尾只需要返回对$quene的判断
  29. return (bool)!$quene;
  30. }
  31. var_dump(checkClose($c));

4. 运行结果:

在服务器命令行模式中运行结果如下:

[root@047 php]# php close.php -c='req(9[09]pp{rew}'
接收字符串:req(9[09]pp{rew}
闭合判断结果:bool(false)

[root@047 php]# php close.php -c='req(9[09]pp{rew})'
接收字符串:req(9[09]pp{rew})
闭合判断结果:bool(true)

经典面试题二、一个玩家进游戏场地分配号码的php代码实现

1. 题目内容:

    一个简单的容易在面试中碰到的动手编码题,一个游戏场地最多只能容纳200个玩家,每个玩家都有一个号码,号码的范围从0~199,全程不断地有玩家进进出出,但是每个在场玩家的号码各不相同。 请设计一个类TicketsPool,负责给进去的玩家分配号码(给出玩家申请号码的实现,并给出你觉得应该有的成员方法,代码可以适当加注释)以及用户退出的方法实现。

2. 解答思路:

    实现起来也简单,可以设想有一套玩家用户系统,经过玩家基本账号验证之后进入玩家游戏场地,我这里就用的玩家的名称作为进入的唯一标记吧,当然可以使用用户uid,只要保障每次进来的时候能正确分配号码,不会冲突,如果出现房间满员能返回满员的信息。

3. PHP编程实现:

  1. <?php
  2. #玩家入场退出类
  3. class TicketsPool{
  4. static $numArr = array();
  5. #成员初始化进入
  6. public function getNum($username){
  7. //同一用户重入
  8. $key = array_search($username, self::$numArr);
  9. if($key!==false){
  10. return $key;
  11. }
  12. #查找空号码
  13. #for($i=0; $i<200; $i++){
  14. for($i=0; $i<5; $i++){
  15. if(!isset(self::$numArr[$i])){
  16. self::$numArr[$i] = $username;
  17. return $i;
  18. }
  19. }
  20. #满员
  21. return false;
  22. }
  23. #成员退出
  24. public function logout($username){
  25. $key = array_search($username, self::$numArr);
  26. if($key!==false){
  27. unset(self::$numArr[$key]);
  28. return true;
  29. }else{
  30. #非法调用
  31. return false;
  32. }
  33. }
  34. }
  35. $TicketsPool = new TicketsPool();
  36. $gamerArr = array( 'tomorrow', '哈哈', '国庆了', '大飞机', '歼20', '快递来了', '再来一个');
  37. foreach($gamerArr as $username){
  38. $room_id = $TicketsPool->getNum($username);
  39. if($room_id !== false){
  40. echo $username."-分配号码:".$room_id,"\n";
  41. }else{
  42. echo $username."--分配失败:房间满员了\n";
  43. echo "国庆了 退出房间:退出".($TicketsPool->logout('国庆了')?'成功':'失败')."\n";
  44. }
  45. }

4. 运行结果:

在linux上执行结果如下:

[root@007 php]# php game.php 
tomorrow-分配号码:0
哈哈-分配号码:1
国庆了-分配号码:2
大飞机-分配号码:3
歼20-分配号码:4
快递来了--分配失败:房间满员了
国庆了 退出房间:退出成功
再来一个-分配号码:2

经典面试题三、php从给定字符串中提取出所有回文串字符的代码实现

1. 题目内容:

    php从字符串中提出回文串数据,什么是回文串?回文串是一个正读和反读都一样的字符串,比如abcba或者abba等等就是回文串。今天看到了一道回文串相关的题目:给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?输出需要删除的字符个数。

    这是网上有人记录的遇到的面试题,我到还没有碰到过,于是就当自己去面试吧,拿到题后就自己开始考虑接着就开始干了,事情都是越想越清楚,在慢慢地尝试和试错中解决,晚上也在未借助任何外力进行实现了,不知道网上有没有同样的实现方法。虽然我自己能单独完成,但我不得不承认,如果是在一个面试环境,同时时间又有限的情况下,我也无法保证自己能做出来。更不要说考虑性能了。

2. 解答思路:

    思路也很简单,回文串肯定至少有2个字符,可以是奇数个也可以是偶数个,所以拿到一个字符串,直接从第2个字符开始我将字符切成左右两边,然后同时从中间出发去两边寻找同样的字符以达到回文,如果找到了就表示这个字符可以在回文串中,并进行记录。同时把两段字符分别从中间删除掉查找过的字符或者部分字符(因为这部分不会再有可能出现在回文串中),一直到左边或者右边的字符串为空,最终查出了整个字符串中所有可能的回文串,再从这些回文串数据列表里查找最长的回文串就不是问题了。

3. PHP编程实现:

具体完整实现的php代码如下:

  1. <?php
  2. #入参检查
  3. $args = getopt('c:');
  4. extract($args);
  5. if(empty($c)) exit('need param:c');
  6. echo "入参c:{$c}\n";
  7. #调用实例
  8. $BackChar = new BackChar();
  9. print_r($BackChar->getBackChar($c));
  10. #回文串实现类
  11. class BackChar{
  12. #定义一个数组存储字符
  13. private $char;
  14. public $backArr = array();
  15. #每个位置开始尝试寻找回文串
  16. protected function calcute($i, $odd=true){
  17. #从中间开始向两边尝试找回串,将查找寄数个和偶数个字符的方式合并
  18. $left = substr($this->char, 0, $i);
  19. $right = substr($this->char, $odd?($i+1):$i);
  20. $c = $odd?$this->char{$i}:'';
  21. $ok = '';
  22. $index_l = strlen($left);
  23. while($left && $right){
  24. $val = substr($left, $index_l - 1, 1);
  25. $left= substr($left,0,-1);
  26. #如果找到了,则说明可以关闭一组字符
  27. $index_r = strpos($right, $val);
  28. if($index_r !== false){
  29. $ok.=$val;
  30. $right = substr($right, $index_r +1);
  31. }
  32. $index_l --;
  33. }
  34. #只有在找到了匹对的字符才认为是有回串
  35. if($ok){
  36. $key = strrev($ok).$c.$ok;
  37. $this->backArr[$key] = strlen($key);
  38. }
  39. }
  40. #供外部调用的方法
  41. public function getBackChar($char){
  42. $this->char = $char;
  43. #循环尝试回文串的位置
  44. for($i=1; $i<strlen($char)-1; $i++){
  45. #尝试找出所有奇数个回文串字符
  46. $this->calcute($i);
  47. #尝试找出偶数个回文串字符
  48. $this->calcute($i, false);
  49. }
  50. #返回所有的回文串字符串
  51. return $this->backArr;
  52. }
  53. }

4. 运行结果:

linux服务器上执行结果如下:

  1. [root@007 php]# php back.php -c=helloworld
  2. 入参c:helloworld
  3. Array
  4. (
  5. [lll] => 3
  6. [ll] => 2
  7. [lol] => 3
  8. [lowol] => 5
  9. [lool] => 4
  10. [lrl] => 3
  11. )
  12. [root@007 php]# php back.php -c=abcdehkkkabzhtt99ba
  13. 入参c:abcdehkkkabzhtt99ba
  14. Array
  15. (
  16. [aba] => 3
  17. [aa] => 2
  18. [abcba] => 5
  19. [abba] => 4
  20. [abdba] => 5
  21. [abeba] => 5
  22. [abhba] => 5
  23. [abhkhba] => 7
  24. [abhhba] => 6
  25. [abhkkkhba] => 9
  26. [abhkkhba] => 8
  27. [abhahba] => 7
  28. [abzba] => 5
  29. [abtba] => 5
  30. [abttba] => 6
  31. [ab9ba] => 5
  32. [ab99ba] => 6
  33. )

    后在网上看到说这个问题可从两个字符间的最大子串角度来思考,我到没去想这块,只是把目标一步一步实现了吧,当然这个方法肯定还有改进的余地,等下回有时间有闲再看看吧。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/868330
推荐阅读
相关标签
  

闽ICP备14008679号