【发布时间】:2019-01-03 15:57:26
【问题描述】:
我是 PHP 新手。我有一个可以工作的函数(从函数内打印到屏幕上的值正是我所期望的),但有时只返回答案(其他时候它返回NULL)。我相信我已将错误与涉及我使用 PHP 的 static 功能的事情隔离开来,但我不确定我到底是如何违反/如何修复它。我试图通过创建一个新的非静态变量来存储结果来解决这个问题,这将我的代码从总是返回NULL 改进为只有时返回NULL。错误函数是我编写的一个更大的程序套件的一部分,因此我将包括它和我用来检查它是否工作的测试函数。
probGen.php
<?
require_once("randX.php");
require_once("../displayArray.php");
error_reporting(E_ERROR | E_WARNING | E_PARSE);
function probGen(array $arr, float $control = 0.01)
/*
* Generates a valid, random probability distribution for a given array of elements, that can be used in conjunction with "probSelect()".
* Input:
$arr: An array of elements.
$control: A value that decides how much mass is allowed to be unilaterally dumped onto one element. A high value would permit distributions where most of the mass is concentrated on one element.
If an invalid value is provided, the default is used.
* Output: An associative array where the keys are the elements in the original array, and the values are their probabilities.
*/
{
$control = ($control <= 1 && $control >= 0)?($control):(0.01); #Use the default value if an invalid number is supplied.
static $result = []; #Initialises $result with an empty array on first function call.
static $max = 1; #Initialises $max with 1 on first function call.
foreach ($arr as $value)
{
$x = randX(0, $max); #Random probability value.
$result[$value] = ($result[$value] + $x)??0; #Initialise the array with 0 on first call, and on subsequent calls increment by $x to assign probability mass.
$max -= $x; #Ensures that the probability never sums to more than one.
}
print("<br>sum = ".array_sum($result)."<br><br>");
displayArray($result);
/*
* After the execution of the above code, there would be some leftover probability mass.
* The code below adds it to a random element.
*/
$var = array_values($arr);
if($max <= $control) #To limit concentration of most of the probability mass in one variable.
{
$result[$var[rand(0,(count($var)-1))]] += $max; #Selects a random key and adds $max to it.
displayArray($result);
print("<br>sum = ".array_sum($result)."<br><br>");
$sol = $result;
return $sol;
}
else
probGen($arr, $control);
}
?>
test.php
<?
/*
* This file contains some functions that can be used for assigning probabilities to an array of elements or selecting an element from said array with a given probability.
*/
require_once("../displayArray.php");
require_once("confirm.php");
require_once("randX.php");
require_once("probGen.php");
require_once("probSelect.php");
$test = ["California" => 0.37, "Florida" => 0.13, "New York" => 0.28, "Washington" => 0.22];
$testX = array_keys($test);
var_dump(probGen($testX));
/*for ($i=0; $i < 100 ; $i++)
{
print(var_dump(confirm(probGen($testX))));
}*/
?>
通过测试,我已经能够确定如果递归发生多次,probGen() 会失败。
【问题讨论】:
-
您需要在 else 块中返回 probGen 结果。
-
@aynber 我不明白它是如何工作的?在我(当然是有限的)理解
else将控制权转移给probGen(),所以函数调用之后什么都不会被执行?此外,程序的完成不应该发生在 if 块中吗?我认为这可能是因为我没有在最终分配后递减$max,所以它会创建一个无限递归/否则会失败。我现在在移动设备上,一旦我回到我的笔记本电脑上,我会尝试修复。 -
不要将其视为相同的功能,而应将其视为不同的功能。你调用函数 1,它要么返回一个值,要么调用函数 2。函数 2 将一个值返回给函数 1,但函数 1 实际上从未对响应做任何事情,所以它在以太中丢失了。执行
return probGen(...)将返回递归函数的响应。从另一个函数调用一个函数不会转移控制权。另一种看待它的方式是你打电话给朋友#1 并提出问题。他们不知道,所以他们打电话给朋友#2,然后必须给你回电话告诉你答案。 -
@TobiAlafin 添加
return会将probGen()的每个递归调用的结果返回到前一个,最终将返回到初始函数调用。 -
@aynber,刘易斯非常感谢你。我明白我哪里出错了。请将您的评论格式化为答案,以便我接受。