Интерпрeтация мат выражений

Тема в разделе "WASM.ZEN", создана пользователем Smile, 16 янв 2005.

  1. Smile

    Smile New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2004
    Сообщения:
    129
    Написал неболшой модуль для анализа математических выражений (тестовый,для проверки алгоритма).

    -анализ с лева на право

    -без учета приоритетов

    -поддержка унарных/бинарных операторов



    Очень устраивает, и алгоритм простенький, но для правильного вычисления нужно явно задать приоритеты (расставить скобки).



    Возможно ли это сделать с минимальными потерями(реализаци/скорости)? тк явно нужно будет использовать сортировку и поиск по выражению.



    в архиве исходник и програмка побаловаться.



    [​IMG] 1408204972__math.zip
     
  2. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Сортировка и поиск лишнее, а преобразование к обpатной польской нотации поможет:

    http://algolist.manual.ru/syntax/revpn.php



    Если использовать FPU для вычислений, то очень просто получается реализовать "стэк", точнее, это совсем не нужно будет делать - он уже и так есть в FPU :) (правда сложность выражений будет ограничена, но IMHO достаточно для большинства случаев)
     
  3. Smile

    Smile New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2004
    Сообщения:
    129
    Хм а получилось неплохо, странно что я раньще ей не воспользовался, как-то выглядела неуклюже наверно :))

    [​IMG] _2092187989__polsk.zip
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Теперь ничего не считает ;(

    Помимо этого, проблемы со скобочками: "()()" и, особенно, с ")("
     
  5. Smile

    Smile New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2004
    Сообщения:
    129
    Это я слентяйнчал, просто алгорит перевода в польскую прверить хотел:)
     
  6. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Как я уже успел понять (спасибо captain cobalt) - самое сложное в подобных вещах не сам разбор / вычисление выражений, а отбраковка неправильных.



    Вот ещё пример: (5(6))



    Кстати, проверку корректности выражений можно делать на основе состояния стэка после вычислений. Правда нужно учесть пару нюансов со скобочками..
     
  7. khv_test

    khv_test New Member

    Публикаций:
    0
    Регистрация:
    30 июн 2004
    Сообщения:
    135
    вот исходник проверки писал как-то для инста..

    проверял все ок.. тока для грамматики

    G({a,b,c,+,-,*,/,(,)},{S,T,F},P,S)

    P:

    S->S+T|S-T|T

    T->T*F|T/F|F

    F->(S)|a|b|c

    //-------------------------------------------------------------------- ---------

    static char symbol[]="abc";

    static char operand[]="+-/*";

    static char mean[]="()";

    //-------------------------------------------------------------------- ---------

    bool one_of(char ch,char *s)

    {

    bool res;

    int l;



    res=false;

    l=lstrlen(s);

    for(int i=0;i<l;i++)

    {

    if(s==ch)

    {

    res=true;

    break;

    }

    }



    return(res);

    }

    //-------------------------------------------------------------------- ---------

    bool valid_expr(char*s)

    {

    enum ch_t

    {

    TNONE = 0 ,

    TSYMBOL ,

    TOPERAND ,

    TLMEAN ,

    TRMEAN ,

    TUNDEF ,

    }ch;



    bool res;

    int l;

    int iSym,iOperand,iL,iR;



    res=true;

    ch=TNONE;

    iSym=

    iOperand=

    iL=

    iR=0;

    l=lstrlen(s);

    for(int i=0;i<l;i++)

    {

    if(one_of(s,operand))

    {

    iOperand++;

    if(ch==TLMEAN || ch==TOPERAND|| i==0)

    return(false);

    ch=TOPERAND;

    }

    else if(s==('('))

    {

    iL++;

    if(ch==TSYMBOL)

    return(false);

    ch=TLMEAN;

    }

    else if(s==(')'))

    {

    iR++;

    if(ch==TOPERAND || ch==TLMEAN)

    return(false);

    ch=TRMEAN;

    }

    else if(one_of(s,symbol))//if(s>='a'&&s<='c')

    {

    iSym++;

    if(ch==TSYMBOL)

    return(false);

    ch=TSYMBOL;

    }

    else

    {

    return(false);

    }

    }

    if( iL!=iR

    || iOperand>iSym

    || ch==TLMEAN

    || ch==TOPERAND

    || iSym==0

    //|| iOperand==0

    )

    {

    res=false;

    }

    return(res);

    }