【问题标题】:PHP array of strings and arraysPHP 字符串数组和数组
【发布时间】:2016-07-18 19:09:39
【问题描述】:

我正在用 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:"-";}.

【问题讨论】:

  • 为什么sqrt(3)没有分解成[3, "sqrt"]`?
  • 由于您使用的是 RPN,因此您不需要对任何内容进行分组。您应该能够使用简单的平面数组。
  • 这可能对你有帮助:github.com/andig/php-shunting-yard
  • @trincot 我的错误,已编辑。
  • @NovaDenizen 那么我将如何评估可交换性?

标签: php arrays postfix-notation


【解决方案1】:

这是一个将字符串转换为嵌套数组的函数:

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 上运行。

【讨论】:

    【解决方案2】:

    我看不出动态构造这个数组有什么问题。例如,这有效(不是后缀):

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

    上面的两个例子都有相同的输出。

    【讨论】:

      【解决方案3】:

      为了通用性和通用性,您还可以使用关联数组,将它们的角色作为索引,如 {operand1、operand2 和 operator} 之一。 事实上,你上面所说的任何数学表达式都可以是这样的模式:“operand1 operatoroperand2”,不管它们到底有多复杂。

      例子:

      5.pi 将是

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

      sqrt(3) 将是

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

      等等……

      通过这种方式,模型将是可扩展的,您将受益于与索引有关的数组函数系列,而不必担心数组成员的顺序,并且解析器会更简单,恕我直言,更易于编写和读取至少是人类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-09
        • 2013-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-02
        • 2011-11-21
        相关资源
        最近更新 更多