PHP массив строк и массивов

Я пишу программу на PHP (так как она будет сопровождать веб-код для системы оценки математики), и мне нужно создать массив строк и массивов. В частности, я хочу преобразовать что-то вроде

((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:"-";}.

0

Решение

Вот функция, которая сделает преобразование из строки во вложенный массив:

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.

0

Другие решения

Я не вижу, в чем проблема с построением этого массива динамически. Например, это работает (не постфикс):

$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);

Оба приведенных выше примера имеют одинаковый результат.

0

Для универсальности и универсальности вы также можете использовать ассоциативный массив с индексами и их ролями, как в одном из {operand1, operand2 и operator}.
В самом деле, любое математическое выражение, которое вы указали выше, может иметь шаблон: «оператор операнда 1, операнд2», каким бы сложным они ни были в конце.

Пример:

5.pi будет

array('op1'=>5, 'op'=>'*', 'opd2'=>'pi');

sqrt (3) будет

array('op1' => 3, 'op' => 'sqrt', 'opd2' => null); // since sqrt is a unary function

и так далее…

Таким образом, модель была бы расширяемой, вы могли бы извлечь выгоду из семейства функций массива, касающихся индексов, не беспокоясь о порядке элементов массива, и парсер был бы, IMHO, намного проще для написания и чтения человеком, по крайней мере.

0
По вопросам рекламы [email protected]