За последние 24 часа нас посетили 15533 программиста и 1490 роботов. Сейчас ищут 909 программистов ...

Парсер формул

Тема в разделе "PHP для новичков", создана пользователем drzugrik, 4 апр 2011.

  1. drzugrik

    drzugrik Активный пользователь

    С нами с:
    23 мар 2011
    Сообщения:
    7
    Симпатии:
    0
    Здравствуйте уважаемые. Помогите пожалуста начинающему.
    Суть вопроса следущая. Есть файл типа (xml):
    <form>
    <formula>y=n+5*16+(sin(z)-k^8)</formula>
    <ish>k,n,z</ish>
    <rez>y</rez>
    </form>
    Ну вообщем суть наверное понятна, что могут быть совершенно любые вещи, и степени и корни и прочие жуткие математические выражения. Задача вот в чем, как лучше посчитать эту формулу?
    Я сначала думал над польским алгоритмом, но его трудно приводить к понятному виду. Потом думал над строковым калькулятором, но ненашел. Сейчас вот думаю использовать eval(), но вот беда, я незнаю как мне взять переменную из исходных и заменить n на $n, потчем так, чтобы заменилась именно переменная n , а не в выражении sin. Может быть я вообще в корне неправильно мыслю? вообще ненашел ничего подобного на PHP, на C/C++ есть, но т.к. я в нем разбираюсь еще хуже, поэтому мне это непомогает... Подскажите пожалуста.
     
  2. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    $formula = preg_replace('/\bn\b/Usi','\$n', $formula);
    при желании таким образом можно все переменные поменять. \b = граница слова
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    эээ если есть ТАКОЙ xml, то жизнь становится простой. =) нужно взять из ish, разбить explode по запятой и для каждого члена получившегося массива найти его чистые вхождения в строке. т.е. я хз как это сделать регуляркой, но мне кажется можно и это не сложно. суть проста: ни до ни после вхождения не должно быть буквы =)
    по-моему это знак \W

    соотв, регулярка должна выглядеть примерно как \W*$val\W* =)
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    во

    PHP:
    1. <?php
    2.  
    3. $formula = 'n+5*16+(sin(z)-k^8)+k';
    4. $vars = "k,n,z";
    5.  
    6. $vars = explode(',', $vars);
    7.  
    8.  
    9. foreach ($vars as $val) {
    10.   $formula = preg_replace('/(\W+|^)' . $val . '(\W+|$)/', '$1\$' . $val . '$2', $formula);
    11. }
    12. echo "Считаем форумулу $formula<br>\n";
    13.  
    14. for ($k = 0; $k < 5; $k++) {
    15.   for ($n = 0; $n < 1000; $n+=100) {
    16.     for ($z = 0; $z < 360; $z+=30) {
    17.       eval('$r=' . $formula . ';');
    18.       echo "$r<br>\n";
    19.     }
    20.   }
    21. }
    22.  
    23.  
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    drzugrik
    если не против, выскажу мнение которое сложилось, пока кодил. если мы заинтересованы вычислить формулу и получить какое-то конкретное значение, то нам в xml-ке ни "y=" ни "<rez>y</rez>" не нужны вобще-то. Т.е. если известно что формула вся живет с одной стороны знака равно, то по сути, мы можем не писать ничего, что находится с другой.

    Т.е. если бы было 5y+3x^n = 12x*y/n, то тогда бы конечно нужно было бы париться с вычислением. Но т.к. любой маломальский школьник уже способен привести такое выражение к виду y= или просто не стоит такой задачи и все формулы будут такие, то есть смысл просто либо не париться этой частью идаже не писать ее в xml, или можно тупо резать и вычислять.
     
  6. drzugrik

    drzugrik Активный пользователь

    С нами с:
    23 мар 2011
    Сообщения:
    7
    Симпатии:
    0
    igordata
    Большое человеческое спасибо!!!
    Про регулярные выражения я даже и недогадался.. Может быть в процессе действительно это и непонадобится. Дело в том что еще будет модуль статического графика и динамического. По той формуле которая считается. А xml-ек там будет (ну покрайней мере расчитывается) не один десяток и в каждом файле примерно по десятку формул. А также хотелось чтобы любой желающий мог дописать формулу от себя. Но я с Вами согласен, лишняя информация будет только путать и занимать место.
    Еще раз - Огромное Вам Спасибо за помощ!!!
     
  7. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    Есть и такое решение. Но лучше \b, тогда не надо учитывать начало и конец строки. получается нагляднее
    Код тот же:
    PHP:
    1. <?
    2.     foreach ($vars as $val) {
    3.         $formula = preg_replace('/\b('.$val.')\b/', '\$\1', $formula);
    4.     }
    5. ?>
     
  8. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я не знаю, что такое \b. я в регулярках вобще лох =)