【问题标题】:How to check if while() is endless?如何检查 while() 是否无穷无尽?
【发布时间】:2014-07-21 14:23:16
【问题描述】:

所以让我简短地解释一下这个概念: 从列表中为用户分配一个随机名称。它检查是否有人已经拥有该名称,如果是这样,它将运行名称 gen 事情,直到找到尚未分配的名称。
所以到目前为止效果很好,我遇到的唯一问题是无法检查列表中的所有用户名是否都已分配。当然,我可以建立一个计数器并检查它是否运行了 1000 次,但这不是一个干净的解决方案,也不是真正的万无一失。我会告诉你我的意思:

    $foundCl = false;
    while($foundCl == false){ // Get Callname n stuff
        $Cl = getCallname(); // <- selects a random name from a list

        $lFoundCl = true;
        $sql = mysql_query("SELECT * FROM Board_Callnames WHERE TID='$TID'");
        while ($row = mysql_fetch_array($sql)){  // Checks if the name is already assigned
            if($row['Callname'] == $Cl['callname']){
                $lFoundCl = false;
            }
        }

        if($lFoundCl == true){ // Found a name that isnt assigned yet, assign it to the user, dont worry about all the values here and the Cl[color] stuff
            $foundCl = true;
            $Cln = $Cl['callname'];
            $Clc = $Cl['color'];
            $ClEntry = mysql_query("INSERT INTO Board_Callnames (TID, UID, Callname, Color, Flair) VALUES ('$TID', '$UID', '$Cln', '$Clc', '0')");
        } else {
            $foundCl = false;
        }
        /* What I need:
        if(this == endless){ break; }
        */
    }

获取呼叫名称:

 function getCallname()
{
$callnames = array(0 => "Alfa", 1 => "Bravo", 2 => "Charlie"); // etc....

$colors = array(0 => "default", 1 => "primary", 2 => "success", 3 => "info", 4 => "warning", 5 => "danger", 6 => "lila", 7 => "poison", 8 => "wine"); // NOT IMPORTANT FOR THIS

$ran_cl = rand(0, count($callnames)-1); // Selects random values
$ran_co = rand(0, count($colors)-1);

return array("callname" => $callnames[$ran_cl], "color" => $colors[$ran_co]); //Return these
}

【问题讨论】:

  • 这是停机问题,本身无法解决。
  • 请将getCallname的正文添加到您的问题中。
  • 您可以做的是添加有限的尝试次数,例如 10 或 100 次。
  • 这段时间无论如何都不会结束......
  • 不是随机检查名称,而是获取完整列表,完全随机化,然后循环遍历它们。

标签: php loops while-loop


【解决方案1】:

解决此问题的一种方法是通过检查每个候选人来构建可用名称列表,然后从尚未被选中的名称中选择一个随机名称。如果可用列表是空的,那么你已经用完了。

【讨论】:

    【解决方案2】:

    整个逻辑似乎是错误的。

    而不是从所有项目的列表中生成一个随机项目,然后检查它是否已分配,您应该从未分配的项目列表中生成一个随机项目,例如:

    SELECT * FROM `itemlist` WHERE `assigned` = 0 LIMIT 1
    

    【讨论】:

    • 如果我只做一次会很有意义,但我需要这样 100 次,所以该选项不可用
    • @user3112337 我真的不明白为什么你需要这样做的次数会影响任何事情。请解释
    • 每次需要时我都需要创建新的列表条目
    【解决方案3】:

    除了将可能的“调用名称”和“颜色”存储在 PHP 数组中之外,您可能还希望将它们移动到数据库中并为它们分配 ID。

    然后您可以创建一个返回随机未分配名称 ID(如果可用)或空结果集(如果没有可用名称)的查询...例如:

    SELECT cn.id FROM callnames cn
    LEFT JOIN Board_Callnames bcn ON bcn.callname = cn.callname
    WHERE bcn.callname IS NULL
    ORDER BY RAND() LIMIT 1
    

    显然,如果您使用 ID 作为名称,您可能希望更改 Board_Callnames 表,以便它不存储字符串而是名称 ID...(并相应地更改我的查询)但这取决于您的内容正在尝试做。


    我刚刚意识到这也可以在没有 ID 的情况下工作。您需要一个表,其中一列包含可用的调用名称。然后,您可以使用此查询来获取随机可用的呼叫名称:

    SELECT cn.callname FROM callnames cn
    LEFT JOIN Board_Callnames bcn ON bcn.callname = cn.callname
    WHERE bcn.callname IS NULL
    ORDER BY RAND() LIMIT 1
    

    【讨论】:

      【解决方案4】:

      您可以检查您的数据库中是否已经有 count($callnames) 用户,因为这是可能的最大名称数。

      【讨论】:

      • 这样做并不能确保每个名称都会被处理。它可能会在同一个名称上迭代多次。 StepeP 的解决方案似乎更好。顺便说一句,这取决于 OP 正在寻找什么。
      猜你喜欢
      • 2011-06-11
      • 2014-10-09
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多