PHP 字符串数组和数组
PHP array of strings and arrays
我正在 PHP 中编写一个程序(因为它将伴随数学评分系统的 Web 代码),我需要创建一个字符串数组和数组。具体来说,我想转换成
((4)+((5)*(pi)))-((9)*(sqrt(3)))
到
[["4", ["5", "pi", "*"], "+"], ["9", ["3", "sqrt"], "*"], "-"]
这是逆向抛光符号的数组格式。有了这个,我将评估跨运算符的可交换性,以将正确的、存储的答案与学生的答案进行比较。但是,由于行的不均匀性,我无法在 PHP 中使用多维数组执行此操作。
如果有办法使用字符串来做到这一点,那会更有帮助(因为我计划将结果存储在 SQL 数据库中),但为此我可能会使用 serialize()
.
感谢您的帮助。
编辑:我想我已经成功了。使用短数组表示法似乎会导致问题。旧的 array()
表示法似乎可以正常运行,如下所示:
array(array("4", array("5", "pi", "*"), "+"), array("9", array("3", "sqrt"), "*"), "-")
和序列化符号(用于存储在数据库中)是:
a:3:{i:0;a:3:{i:0;s:1:"4";i:1;a:3:{i:0;s:1:"5";i:1;s:2:"pi";i:2;s:1:"*";}i:2;s:1:"+";}i:1;a:3:{i:0;s:1:"9";i:1;a:2:{i:0;s:1:"3";i:1;s:4:"sqrt";}i:2;s:1:"*";}i:2;s:1:"-";}.
我看不出动态构建这个数组有什么问题。例如,这有效(不是后缀):
$test_array = array(
array(
"4",
array(
"5",
"pi",
"*"
),
"+"
),
array(
"9",
array(
"3",
"sqrt"
),
"*"
),
"-"
);
var_dump($test_array);
因此,使用您的算法动态执行此操作的行为应该与执行此操作的方式类似(当然,添加元素的顺序取决于您的算法):
$test_array2 = array();
$test_array2[] = array();
$test_array2[] = array();
$test_array2[] = "-";
$test_array2[1][] = "9";
$test_array2[1][] = array();
$test_array2[1][1][] = "3";
$test_array2[1][1][] = "sqrt";
$test_array2[1][] = "*";
$test_array2[0][] = "4";
$test_array2[0][] = array();
$test_array2[0][1][] = "5";
$test_array2[0][1][] = "pi";
$test_array2[0][1][] = "*";
$test_array2[0][] = "+";
var_dump($test_array2);
上面的两个例子有相同的输出。
这是一个函数,可以将字符串转换为嵌套数组:
function convert($string) {
function nest(&$base) {
$result = [];
while (($ch = array_shift($base)) !== null) {
if ($ch === ')') break;
$result[] = $ch === '(' ? nest($base) : $ch;
}
if (count($result) < 2) return reset($result);
// Move operator to the end of the array:
$result[] = array_splice($result, -2, 1)[0];
return $result;
}
// split string into parts, where each bracket is a separate part
$base = preg_split("/([()])/", $string, 0, PREG_SPLIT_DELIM_CAPTURE
+ PREG_SPLIT_NO_EMPTY);
// recursively build nested postfix structure
return nest($base);
}
你可以这样称呼它:
$result = convert($string);
对于问题中提供的示例输入,输出为:
array (
array (
'4',
array (
'5',
'pi',
'*',
),
'+',
),
array (
'9',
array (
'3',
'sqrt',
),
'*',
),
'-',
)
注意函数sqrt
也被分离为后缀函数
在 eval.in 上查看 运行。
为了多功能性和通用性,您还可以使用关联数组,将它们的角色作为索引,如 {operand1、operand2 和 operator} 之一。
事实上,您在上面陈述的任何数学表达式都可以是这种模式:"operand1 operator operand2",无论它们最终有多复杂。
示例:
5.pi 将是
array('op1'=>5, 'op'=>'*', 'opd2'=>'pi');
sqrt(3) 将是
array('op1' => 3, 'op' => 'sqrt', 'opd2' => null); // since sqrt is a unary function
等等...
这样模型将是可扩展的,您将受益于与索引有关的数组函数系列,而无需担心数组成员的顺序,而且解析器将更容易编写,并且是至少被人阅读。
我正在 PHP 中编写一个程序(因为它将伴随数学评分系统的 Web 代码),我需要创建一个字符串数组和数组。具体来说,我想转换成
((4)+((5)*(pi)))-((9)*(sqrt(3)))
到
[["4", ["5", "pi", "*"], "+"], ["9", ["3", "sqrt"], "*"], "-"]
这是逆向抛光符号的数组格式。有了这个,我将评估跨运算符的可交换性,以将正确的、存储的答案与学生的答案进行比较。但是,由于行的不均匀性,我无法在 PHP 中使用多维数组执行此操作。
如果有办法使用字符串来做到这一点,那会更有帮助(因为我计划将结果存储在 SQL 数据库中),但为此我可能会使用 serialize()
.
感谢您的帮助。
编辑:我想我已经成功了。使用短数组表示法似乎会导致问题。旧的 array()
表示法似乎可以正常运行,如下所示:
array(array("4", array("5", "pi", "*"), "+"), array("9", array("3", "sqrt"), "*"), "-")
和序列化符号(用于存储在数据库中)是:
a:3:{i:0;a:3:{i:0;s:1:"4";i:1;a:3:{i:0;s:1:"5";i:1;s:2:"pi";i:2;s:1:"*";}i:2;s:1:"+";}i:1;a:3:{i:0;s:1:"9";i:1;a:2:{i:0;s:1:"3";i:1;s:4:"sqrt";}i:2;s:1:"*";}i:2;s:1:"-";}.
我看不出动态构建这个数组有什么问题。例如,这有效(不是后缀):
$test_array = array(
array(
"4",
array(
"5",
"pi",
"*"
),
"+"
),
array(
"9",
array(
"3",
"sqrt"
),
"*"
),
"-"
);
var_dump($test_array);
因此,使用您的算法动态执行此操作的行为应该与执行此操作的方式类似(当然,添加元素的顺序取决于您的算法):
$test_array2 = array();
$test_array2[] = array();
$test_array2[] = array();
$test_array2[] = "-";
$test_array2[1][] = "9";
$test_array2[1][] = array();
$test_array2[1][1][] = "3";
$test_array2[1][1][] = "sqrt";
$test_array2[1][] = "*";
$test_array2[0][] = "4";
$test_array2[0][] = array();
$test_array2[0][1][] = "5";
$test_array2[0][1][] = "pi";
$test_array2[0][1][] = "*";
$test_array2[0][] = "+";
var_dump($test_array2);
上面的两个例子有相同的输出。
这是一个函数,可以将字符串转换为嵌套数组:
function convert($string) {
function nest(&$base) {
$result = [];
while (($ch = array_shift($base)) !== null) {
if ($ch === ')') break;
$result[] = $ch === '(' ? nest($base) : $ch;
}
if (count($result) < 2) return reset($result);
// Move operator to the end of the array:
$result[] = array_splice($result, -2, 1)[0];
return $result;
}
// split string into parts, where each bracket is a separate part
$base = preg_split("/([()])/", $string, 0, PREG_SPLIT_DELIM_CAPTURE
+ PREG_SPLIT_NO_EMPTY);
// recursively build nested postfix structure
return nest($base);
}
你可以这样称呼它:
$result = convert($string);
对于问题中提供的示例输入,输出为:
array (
array (
'4',
array (
'5',
'pi',
'*',
),
'+',
),
array (
'9',
array (
'3',
'sqrt',
),
'*',
),
'-',
)
注意函数sqrt
也被分离为后缀函数
在 eval.in 上查看 运行。
为了多功能性和通用性,您还可以使用关联数组,将它们的角色作为索引,如 {operand1、operand2 和 operator} 之一。 事实上,您在上面陈述的任何数学表达式都可以是这种模式:"operand1 operator operand2",无论它们最终有多复杂。
示例:
5.pi 将是
array('op1'=>5, 'op'=>'*', 'opd2'=>'pi');
sqrt(3) 将是
array('op1' => 3, 'op' => 'sqrt', 'opd2' => null); // since sqrt is a unary function
等等...
这样模型将是可扩展的,您将受益于与索引有关的数组函数系列,而无需担心数组成员的顺序,而且解析器将更容易编写,并且是至少被人阅读。