Написал неболшой модуль для анализа математических выражений (тестовый,для проверки алгоритма). -анализ с лева на право -без учета приоритетов -поддержка унарных/бинарных операторов Очень устраивает, и алгоритм простенький, но для правильного вычисления нужно явно задать приоритеты (расставить скобки). Возможно ли это сделать с минимальными потерями(реализаци/скорости)? тк явно нужно будет использовать сортировку и поиск по выражению. в архиве исходник и програмка побаловаться. 1408204972__math.zip
Сортировка и поиск лишнее, а преобразование к обpатной польской нотации поможет: http://algolist.manual.ru/syntax/revpn.php Если использовать FPU для вычислений, то очень просто получается реализовать "стэк", точнее, это совсем не нужно будет делать - он уже и так есть в FPU (правда сложность выражений будет ограничена, но IMHO достаточно для большинства случаев)
Хм а получилось неплохо, странно что я раньще ей не воспользовался, как-то выглядела неуклюже наверно ) _2092187989__polsk.zip
Как я уже успел понять (спасибо captain cobalt) - самое сложное в подобных вещах не сам разбор / вычисление выражений, а отбраковка неправильных. Вот ещё пример: (5(6)) Кстати, проверку корректности выражений можно делать на основе состояния стэка после вычислений. Правда нужно учесть пару нюансов со скобочками..
вот исходник проверки писал как-то для инста.. проверял все ок.. тока для грамматики 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); }