搜索数组内部的内容并返回它旁边的内容

时间:2013-12-21 16:48:11

标签: php arrays

H2O -> H2 + O2

我将前一个字符串转换为两个数组:

Array ( [0] => H2 [1] => O2 ) 
Array ( [0] => H2O ) 

我还从字符串中创建了另一个数组,它获取了反应中的所有元素

Array ( [0] => H [1] => O ) 

我要做的是获取元素旁边的数字并从中创建一个数组。在这种情况下,我试图实现这样的目标:

数组找到等式中H旁边的数字

Array ( [0] => 2 [1] => 0 ) 
Array ( [0] => 2 ) 

数组找到等式中O旁边的数字

Array ( [0] => 0 [1] => 2 ) 
Array ( [0] => 1 ) 

基本上在此表中展示:

    H2      +      O2    ->       H2O
H:   2             0               2
O:   0             2               1

我怎样才能实现这样的目标。我正在努力创造一种化学平衡器,我陷入了这一步。

更高级的问题..当搜索元素时,如果你有这样的元素:Ba(NO3)2你怎么能在创建数组时考虑2个氮和6个氧。

3 个答案:

答案 0 :(得分:1)

我有兴趣解决您的问题,但我尝试使用OOP解决它。首先,应该对数据结构进行建模。因此,问题可以清楚地解决。

这是我的工作代码(它需要PHP> = 5.3):

<?php

$h2 = Element::fromString('H2');
//var_dump($h2->getName()); // H
//var_dump($h2->getNumber()); // 2

$o2 = Element::fromString('O2');
//var_dump($o2->getName()); // O
//var_dump($o2->getNumber()); // 2

$h2o = ElementGroup::fromString('H2O');
foreach ($h2o->getElements() as $element) {
    var_dump($element->getName());
    var_dump($element->getNumber());
}
// this should print :
// H
// 2
// O
// 1

/* element for H2 or O2 */
class Element
{
    /* example : H */
    private $name;

    /* example : 2 */
    private $number;

    public function __construct($name, $number = 0)
    {
        $this->name = $name;
        $this->number = $number;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getNumber()
    {
        return $this->number;
    }

    public static function fromString($string)
    {
        preg_match('/([a-zA-Z])(\d*)/', $string, $matches);

        $element = new self($matches[1], ($matches[2] != '') ? (int)$matches[2] : 1);
        return $element;
    }
}

/* H2O */
class ElementGroup
{
    private $elements = array();

    public function addElement(Element $element)
    {
        $this->elements[] = $element;
    }

    public function getElements()
    {
        return $this->elements;
    }

    public static function fromString($string)
    {
        preg_match_all('/[a-zA-Z]\d*/', $string, $matches);

        $elementGroup = new self();
        if (!empty($matches)) {
            foreach ($matches[0] as $elementString) {
                $elementGroup->addElement(Element::fromString($elementString));
            }
        }

        return $elementGroup;
    }
}

答案 1 :(得分:1)

试试这个:

function make(array $arr, $fullName) {
    $struct = array(
        $fullName => array()
    );

    foreach ($arr as $item) {
        $atomAmount = preg_replace('/[^0-9]/', '', $item);
        $atomName = str_replace($atomAmount, '', $item);

        $struct[$fullName][$atomName] = (int) $atomAmount;
    }

    return $struct;
}

make(array('H2', 'O2'), 'H2O');

此函数返回:

array (size=1)
  'H2O' => 
    array (size=2)
      'H' => int 2
      'O' => int 2

我认为这种数组结构更好。

答案 2 :(得分:1)

<?php
    function chemistry($arr)
    {
        $result = array();
        array_walk($arr, function($value) use (&$result)
        {
            preg_match_all("#([A-Z][a-z]*)(\d*)#", $value, $match);

            $formula = array_combine($match[1],
                array_map(function($val)
                {
                    if(intval($val) == 0)
                        return "1"; 
                    else
                        return $val;
                }, $match[2]));
            if(count($formula) == 1)
            {
                $result[$match[1][0]] = $formula[$match[1][0]];
            }
            else
                $result = $formula;
        });
        return $result;
    }
    $left = array("H2", "O2");
    $right = array("H2O");
    print_r(chemistry($right));
    print_r(chemistry($left));

<强>输出

Array             # for H2O
(
    [H] => 2
    [O] => 1
)
Array             # for H2, O2
(
    [H] => 2
    [O] => 2
)