【问题标题】:Solving Hydra-Shield - PHP [closed]解决 Hydra-Shield - PHP [关闭]
【发布时间】:2015-10-17 14:42:26
【问题描述】:

下面是这个算法问题的 php 脚本:

神盾局是一个秘密组织,负责 守护世界免受任何灾难。他们的宿敌是 名为 HYDRA 的组织。不幸的是,来自 HYDRA 的一些成员 潜入神盾局营地。神盾局需要找出所有这些 渗透者,以确保它不被入侵。

执行董事兼首席神盾局成员尼克弗瑞发现,神盾局中的每个人都可以向每个人发送求救信号 他熟悉的其他神盾局成员。九头蛇成员可以发送假 向他人发送 SOS 信息以迷惑他人,但他们永远无法收到 来自 SHIELD 成员的 SOS 消息。每个神盾局成员都会收到 一条 SOS 消息会攻击另一名 SHIELD 成员,而后者又会 从另一个神盾局成员那里收到,依此类推,直到 NickFury。盾 有一个复杂的机制来捕捉谁向谁发送了 SOS 信号 谁。鉴于这些信息,尼克需要有人编写程序 可以查看这些数据并找出所有 HYDRA 成员。

Sample Input

Nick Fury : Tony Stark, Maria Hill, Norman Osborn
Hulk : Tony Stark, HawkEye, Rogers
Rogers : Thor, 
Tony Stark: Pepper Potts, Nick Fury
Agent 13 : Agent-X, Nick Fury, Hitler
Thor: HawkEye, BlackWidow
BlackWidow:Hawkeye
Maria Hill : Hulk, Rogers, Nick Fury
Agent-X : Agent 13, Rogers
Norman Osborn: Tony Stark, Thor

Sample Output

Agent 13, Agent-X, Hitler

脚本.php

   <?php
    //this is the input
    $input="Nick Fury : Tony Stark, Maria Hill, Norman Osborn
    Hulk : Tony Stark, HawkEye, Rogers
    Rogers : Thor
    Tony Stark: Pepper Potts, Nick Fury
    Agent 13 : Agent-X, Nick Fury, Hitler
    Thor: HawkEye, BlackWidow
    BlackWidow:HawkEye
    Maria Hill : Hulk, Rogers, Nick Fury
    Agent-X : Agent 13, Rogers
    Norman Osborn: Tony Stark, Thor";

        /*this is an array for storing shield member names as 
           key-value pairs like Nick Fury=>Tony Stark, Maria Hill, Norman Osborn*/
            $shield=array();


            $keys=array();      //array for storing shield member names as keys
            $values=array();    //array for storing shield member names as value


            $shield_members=array();    //array which stores each valid shield member's name using below process
            //$hydra=array();


            $rows = explode("\n", $input);  //creating array of given input row wise



            $i=0;
            //considering each row at once
            while ($i<count($rows)) {
                # code...
                $temp=explode(":", $rows[$i]);  //exploding row
                $key=trim($temp[0]);            //getting key
                $value=trim($temp[1]);          //getting value

                $keys[]=$key;       //storing each key in keys[]

                $values[]=$value;   //storing each value in values[]
                $shield[$key]=$value;   //storing these key-value pair as array in shield[]
                $i++;
            }

            //loop to find all persons who are receiving messages from anyone
            $i=0;
            $recieiver_hydra=array();   //arrray to store all persons receiving messages
            while($i<count($values)){
                $temp = explode(",", $values[$i]); //exploding RHS values row wise
                $j=0;
                while ($j<count($temp)) {
                    # code...
                    if(!in_array($temp[$j], $recieiver_hydra))  //trying insert only unique values in recieiver_hydra[]
                        $recieiver_hydra[]=$temp[$j];           //========BUT NOT GETTING=======
                    $j++;

                }

                $i++;
            }


        $shield_members[]= "Nick Fury"; //starting from Nick Fury

        $temp = explode(",",$shield["Nick Fury"]);  //getting value from shield[] array for given key

        $i=0;
        while($i<count($temp)){
            $shield_members[]= $temp[$i];   //adding shield members which are valid not the hydra people
            $i++;
        }

        /* searching process for each valid shield member starting from nick fury upto last one found
            and storing them in the sheil_members[] array  */
        for($i=1; $i<30; $i++){         //=============HERE DON'T GETTING WHAT SHOULD BE THE CONDITION TO STOP EXECUTING
            if (array_key_exists(trim($shield_members[$i]),$shield))
                $temp = explode(",",$shield[trim($shield_members[$i])]);
            else continue;
             $j=0;
             while ($j<count($temp)) {
                # code...

                $shield_members[] = trim($temp[$j]);
                $j++;
             }


        }


        $i=0;
        //printing all valid members added to shield_members[] including duplicate values
        while ( $i<count($shield_members)) {
            # code...
            echo $shield_members[$i]."<br>";
            $i++;
        }

        asort($shield_members); //sorting them

        $res1 = array_diff($keys, $shield_members);     //finding difference and getting HYDRA members from LHS
        $res2= array_diff($recieiver_hydra, $shield_members);   //finding difference and getting HYDRA members from RHS ======BUT NOT GETTING





    /*
    <form action=<?php echo $_SERVER["PHP_SELF"]?> method="POST">
    **<i> Enter input in the textarea... </i>
    <textarea name="input" rows="10" cols="90"></textarea><br>
    <input type="submit" name="submit" value="Find HYDRA Members">

    </form>
    */
    ?>

根据我的编码和期望,$res1 必须拥有来自 LHS 输入的所有 HYDRA 成员,$res2 必须拥有来自 RHS 输入的所有 HYDRA 成员。 但是在打印它们时,我得到了错误的结果。

$res1 = Array ( [4] => Agent 13 [8] => Agent-X )   //THIS IS CORRECT
$res2 = Array ( [3] => HawkEye [4] => Rogers [7] => Nick Fury 
                [8] => Agent-X [9] => Hitler [11] => BlackWidow 
                [13] => Agent 13 [14] => Thor )  //WRONG RESULTS

请帮助我知道我做错了什么? (我不是算法专家。我使用原始编码思想和知识编写了整个代码。)

【问题讨论】:

    标签: php arrays algorithm sorting


    【解决方案1】:

    这听起来像是一些编程课程的练习。通常我会说,你应该自己解决这样的任务(我认为这将是你的问题被否决的原因),但这是一个有趣的问题,所以这是我的解决方案。

    如果我需要实现一个新算法,我总是尝试将问题分解为子问题。 这样做,

    • 更容易找到好的解决方案
    • 因此您会得到更易读的代码

    所以第一个问题是将输入转换为一个数组结构来处理:

    function transformInput($input) {
      foreach (explode("\n", $input) as $row) {
        list($receiver, $senders) = explode(':', $row);
        $memberTree[trim($receiver)] = array_map('trim', explode(',', $senders));    
      }
      return $memberTree;
    }
    

    第二个问题是找到所有真正的神盾局成员:

    function extractShieldMembers($memberTree, $startMember, $shieldMembers = array()) {
      $shieldMembers[] = $startMember;  
      if (array_key_exists($startMember, $memberTree)) {
        foreach ($memberTree[$startMember] as $member) {
          if (!in_array($member, $shieldMembers)) {
            $shieldMembers = array_merge(
              $shieldMembers, 
              extractShieldMembers($memberTree, $member, $shieldMembers)
            );
          }
        }
      }
      return $shieldMembers;
    }
    

    通过库中的这两个函数,很容易获得所有 SHIELD 成员的列表:

    $memberTree = transformInput($input);
    $shieldMembers = array_unique(extractShieldMembers($memberTree, 'Nick Fury'));
    

    现在,在知道谁真正属于 SHIELD 之后,您可以使用此功能找到所有 HYDRA 成员:

    function getHydraMembers($memberTree, $shieldMembers){
      $allMembers = array();
      foreach ($memberTree as $key => $value) {
        $allMembers[] = $key;
        $allMembers = array_merge($allMembers, $value);
      }
      return array_unique(array_diff($allMembers, $shieldMembers));
    }
    
    $hydraMembers = getHydraMembers($memberTree, $shieldMembers);
    

    这是解决此问题的最佳方法吗? 我不这么认为,因为这只是一个快速的方法。 但是正如您所看到的,如果您尝试将代码拆分为小的逻辑函数,您将获得更易读的代码,从而可以更好地进行调试。 您也不需要那么多临时变量和计数器。

    【讨论】:

      猜你喜欢
      • 2016-04-21
      • 2010-12-28
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 1970-01-01
      • 2014-10-22
      • 2013-08-23
      • 2018-07-25
      相关资源
      最近更新 更多