优化递归算法+php,php – 递归(?)算法设计

我要求允许我的最终用户输入公式,就像电子表格一样.我有这样一个数组:

$table = array(

1=>array(

"id"=>1,

"Name"=>"Regulating",

"Quantity"=>"[2]Quantity+[3]Value",

"Value"=>"[2]Cost"

),

...)

第一级数组键的值始终与该数组中的id键相同.

列表示例如下:

id Name Quantity Value

1 Regulating [2]Quantity+[3]Value [2]Cost

2 Kerbs 3 6

3 Bricks 9 7

4 Sausages [3]Cost 3

5 Bamboo [4]Quantity [7]Cost

6 Clams [4]Quantity NULL

7 Hardcore [3]Quantity*0.5 12

8 Beetles [6]Quantity*[4]Value [2]Value

数量和值键表示引用[id]和数量,值或成本的公式.

通过乘以价值和数量得出成本.

我在用:

preg_match_all("/\[(.*?)\]([A-Z]*[a-z]*)/", $string, $matches, PREG_SET_ORDER);

为[1] [数量]输出如此数组:

Array

(

[0] => Array

(

[0] => [2]Quantity

[1] => 2

[2] => Quantity

)

[1] => Array

(

[0] => [3]Value

[1] => 3

[2] => Value

)

)

使用类似于以下内容的方式遍历表:

$calcString = $table [1] [‘Quantity’];`

foreach ($matches as $match) {

$calcString = str_replace($match[0], $table[$match[1]][$match[2]], $calcString);

}

我可以得到要计算的字符串,并使用matheval类来完成总和.

例如

[1]Quantity = [2]Quantity + [3]Value

[2]Quantity = 3

[3]Value = 7 // [1]Quantity = 3 + 7 = 10

[1]Value = [2]Cost

[2]Cost = [2]Quantity * [2]Value // 3 * 6 = 18

基本上,表中的变量引用同一个表中的其他[id]键.

但这是我的问题

我需要解析对表格其他部分的引用(可能是也可能不是公式)来填补空白.这超出了我的舒适范围,我很感激任何建议(甚至更好的功能代码),它提供了我如何能够实现这一目标的启示.

谢谢

解决方法:

一个dangerously简单,特定于您的情况的可执行良好的解决方案!

class solver {

private

// The final output array

$arr_evaled,

// When a cell gains its final value, the corresponding entry in the following array gets marked as being done!

$arr_done;

private $solving_iterations_count;

public function solver($array) {

$this->arr_done = array();

foreach($array as $k => $arr)

$this->arr_done[$k] = array('Quantity' => false, 'Value' => false);

// Firstly,expand all of the "[x]Cost"s to "([x]Quantity*[x]Value)"s!

$this->arr_evaled = array_map(

function($v){ return preg_replace('#\[(\d*?)\]Cost#', '([$1]Quantity*[$1]Value)', $v); },

$array

);

$this->solving_iterations_count = 0;

$this->solve();

}

private function isDone() {

foreach($this->arr_done as $a)

if($a['Quantity'] == false || $a['Value'] == false)

return false;

return true;

}

private function isCellDone($id, $fieldName) {

return $this->arr_done[$id][$fieldName];

}

private function markCellAsDone($id, $fieldName, $evaluation) {

$this->arr_done[$id][$fieldName] = true;

$this->arr_evaled[$id][$fieldName] = $evaluation;

}

private function isEvaluable($str) {

return preg_match('#^[0-9*+-\/\(\)\.]*$#', $str) == 1 || strtolower($str)=='null';

}

private function replace($from, $to) {

foreach($this->arr_evaled as &$arr) {

$arr['Quantity'] = str_replace($from, $to, $arr['Quantity']);

$arr['Value'] = str_replace($from, $to, $arr['Value']);

}

}

private function solve() {

$isSolvable = true; // YOUR TODO: I believe coding this part is also fun!) (e.g: check for "reference cycles")

if(!$isSolvable) return null;

while( !$this->isDone() )

{

foreach($this->arr_evaled as $arr) {

foreach(['Quantity', 'Value'] as $fieldName) {

if(!$this->isCellDone($arr['id'], $fieldName)) {

if($this->isEvaluable($arr[$fieldName])) {

$evaluation = eval("return {$arr[$fieldName]};");

$this->markCellAsDone($arr['id'], $fieldName, $evaluation);

$this->replace("[{$arr['id']}]$fieldName", "$evaluation");

}

}

}

}

$this->solving_iterations_count++;

}

foreach($this->arr_evaled as &$row)

$row['Cost'] = $row['Quantity'] * $row['Value'];

return $this->arr_evaled;

}

public function print_tabulated() {

echo "The count of solving iterations: {$this->solving_iterations_count}
";

echo '

idNameQuantityValueCost

foreach($this->arr_evaled as $arr)

echo "

{$arr['id']}{$arr['Name']}{$arr['Quantity']}{$arr['Value']}{$arr['Cost']}";

echo '

';

}

}

// Testing

$arr = array(

1 => array( 'id' => 1, 'Name' => 'Regulating', 'Quantity' => '[2]Quantity+[3]Value', 'Value' => '[2]Cost' ),

2 => array( 'id' => 2, 'Name' => 'Kerbs', 'Quantity' => '3', 'Value' => '6' ),

3 => array( 'id' => 3, 'Name' => 'Bricks', 'Quantity' => '9', 'Value' => '7' ),

4 => array( 'id' => 4, 'Name' => 'Sausages', 'Quantity' => '[3]Cost', 'Value' => '3' ),

5 => array( 'id' => 5, 'Name' => 'Bamboo', 'Quantity' => '[4]Quantity', 'Value' => '[7]Cost' ),

6 => array( 'id' => 6, 'Name' => 'Clams', 'Quantity' => '[4]Quantity', 'Value' => 'NULL' ),

7 => array( 'id' => 7, 'Name' => 'Hardcore', 'Quantity' => '[3]Quantity*0.5', 'Value' => '12' ),

8 => array( 'id' => 8, 'Name' => 'Beetles', 'Quantity' => '[6]Quantity*[4]Value', 'Value' => '[2]Value' ),

);

echo '

';

(new solver($arr))->print_tabulated();

这是输出:

0BFxF.gif

标签:php,algorithm,recursion

来源: https://codeday.me/bug/20190516/1116839.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值