C/C++ - Задача
|
Новый участник Сообщения: 10 |
Есть такая задача: арифметичиское виражения задаетса как строка, например - 28*4/(4-1).
Надо ево посчитать и взять к вниманию дужки. Мои знание з С - среднее. Хоть подскажыте с чево начать. |
|
Отправлено: 19:12, 29-09-2010 |
DOOMer Сообщения: 3254
|
Профиль | Отправить PM | Цитировать Как бы ты решал это на бумаге?
Нашел первую закрывающую скобку, нашел соответствующую открывающую - очевидно первую слева от закрывающей, вычислил выражение в них, заменил эти "дужки" результатом вычисления и полученную строку начал решать заново. До тех пор, пока не получится в результате одно число. |
------- Отправлено: 19:30, 29-09-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Новый участник Сообщения: 10
|
Профиль | Отправить PM | Цитировать Я хочу кто зделать так - разбить строку на два масиви - цифри и операции потом по приоритету их виполнить а как засунуть туда дужки вобще не представлюю.
|
Отправлено: 19:54, 29-09-2010 | #3 |
DOOMer Сообщения: 3254
|
Профиль | Отправить PM | Цитировать Можно просто строками обойтись:
строка='28*4/(4-1)' нашли первую закрывающую - 10 элемент строки (или последний символ строки, если скобок нет), вернулись налево до первой открывающей - 6 элемент (или до начала строки, если скобок нет), взяли с шестого символа по десятый - '(4-1)', "скормили" результат функции посчитай_мне_простое_выражение('(4-1)'), функция вернула результат '3', заменили в исходной строке подстроку с 6 по 10 элемент полученным значением '3', получили строку строка='28*4/3' если в полученной строке есть что-то, кроме цифр и десятичного разделителя - вернулись на предыдущий шаг в результате получим строка='37.333333333'. Ну а функция посчитай_мне_простое_выражение_без_скобок() - сначала убирает скобки в начале и конце строки, если такие есть, а потом просто проверяет строку слева направо, ищет сначала *, потом /, потом +, потом -, заменяя каждый раз в строке найденное выражение его значением: '(4-1)'->'4-1'->'3' '28*4/3'->'112/3'->'37.333333333' Как-то так ![]() |
------- Отправлено: 20:37, 29-09-2010 | #4 |
Необычный Сообщения: 4463
|
Профиль | Сайт | Отправить PM | Цитировать svdanik, Есть такое понятие - обратная польская запись. (ОПЗ)
Тебе надо будет перевести выражение в него. Это можно осуществить в один проход с использованием стека. + / - однопроходного перевода выражения в ОПЗ + - быстро, удобно для вычисления. - - построенное дерево выражения не всегда оптимально для параллельного вычисления и требует дополнительного анализа. |
|
------- Отправлено: 21:32, 29-09-2010 | #5 |
Ветеран Сообщения: 5624
|
Профиль | Отправить PM | Цитировать svdanik, и научись писать русским языком, а не коверкать простейшие слова.(Если, конечно, русский твой родной язык).
|
------- Отправлено: 01:08, 30-09-2010 | #6 |
![]() Старожил Сообщения: 232
|
Профиль | Сайт | Отправить PM | Цитировать Вот вам арифметический анализатор:
#ifndef __PARSER_H #define __PARSER_H #include <iostream> #include <math.h> #include <map> #include <string> #include <iomanip> using namespace std; typedef map<string,double> tVr; enum Tokens { DELIMITER = 1, VARIABLE, NUMBER, FUNCTION }; enum Function { SIN=5, COS, EXP, LN, LOG10, TAN, SQRT, FABS, ASIN, ACOS, ATAN, SINH, COSH, TANH, FACT, LOG, FMOD, CEIL, FLOOR, SECANT, COSECANT, COTAN, ASEC, ACOSEC, ACOTAN, COSECH, COTANH, ASINH, ACOSH, ATANH, ASECH, ACOSECH, ACOTANH }; #define NUMVARS 26 template <class PType> class CParser { char* exp_ptr; char token[80]; char tok_type; char fun_type; string cur_var; tVr vars; bool IsErr; void eval_exp1(PType& result); void eval_exp2(PType& result); void eval_exp3(PType& result); void eval_exp4(PType& result); void eval_exp5(PType& result); void eval_exp6(PType& result); void atom(PType& result); void get_token(),putback(); void serror(int error); PType find_var(string s); int isdelim(char c); friend long fact(long n); friend PType DecTo(); public: CParser(); ~CParser(); PType eval_exp(char* exp); tVr GetVars(); void SetValue(string var,PType& value); PType GetValue(string var); bool IsError(); }; long fact(long n) { if( (n == 0) || (n == 1) ) return 1; return ( n * fact(n-1) ); } template <class PType> CParser<PType>::CParser() { exp_ptr = NULL; vars["E"] = 2.71828182845904523536; vars["PI"] = 3.14159265358979323846; vars["x"] = 0; } template <class PType> CParser<PType>::~CParser() { exp_ptr = NULL; } template <class PType> PType CParser<PType>::eval_exp(char* exp) { PType result = (PType) 0; exp_ptr = exp; IsErr = false; get_token(); if ( !*token ) { serror(2); return (PType) 0; } eval_exp1(result); if (*token) serror (0); if( IsError() ) return (PType) 0; else return (PType) result; } template <class PType> void CParser<PType>::eval_exp1(PType& result) { char ttok_type; char temp_token[80]; string var; if ( tok_type == VARIABLE) { strcpy(temp_token,token); ttok_type = tok_type; var = cur_var; get_token(); if (*token != '=') { putback(); strcpy(token,temp_token); tok_type = ttok_type; } else { get_token(); eval_exp2(result); if( (var == "E") || (var == "PI") ) serror(72); else vars[var] = result; return; } } eval_exp2(result); } template <class PType> void CParser<PType>::eval_exp2(PType& result) { register char op; PType temp; temp = (PType) 0; eval_exp3(result); while( (op = *token) == '+' || op == '-') { get_token(); eval_exp3(temp); switch(op) { case '-': result = result - temp; break; case '+': result = result + temp; break; } } } template <class PType> void CParser<PType>::eval_exp3(PType& result) { register char op; PType temp; temp = (PType) 0; eval_exp4(result); while( (op = *token) == '*' || op == '/' || op == '%') { get_token(); eval_exp4(temp); switch(op) { case '*': result = result * temp; break; case '/': result = result / temp; break; case '%': result = (int) result % (int) temp; break; } } } template <class PType> void CParser<PType>::eval_exp4(PType& result) { PType temp; temp =(PType) 0; eval_exp5(result); if (*token == '^') { get_token(); eval_exp4(temp); if (temp == 0.0) { result = (PType) 1; return; } result = (PType) pow(result,temp); } } template <class PType> void CParser<PType>::eval_exp5(PType& result) { register char op; op = 0; if ( (tok_type == DELIMITER) && *token == '+' || *token == '-') { op = *token; get_token(); } eval_exp6(result); if (op == '-') result = -result; } template <class PType> void CParser<PType>::eval_exp6(PType& result) { if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(1); get_token(); } else atom(result); } template <class PType> void CParser<PType>::atom(PType& result) { static PType arg1=0,arg2=0; switch (tok_type) { case VARIABLE: result = find_var(cur_var); get_token(); return; case NUMBER: result = (PType) atof(token); get_token(); return; case FUNCTION: switch(fun_type) { case SIN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(5); else result = (PType) sin(result); } else serror(4); get_token(); return; case COS: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(7); else result = (PType) cos(result); } else serror(6); get_token(); return; case EXP: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(9); else result = (PType) exp(result); } else serror(8); get_token(); return; case LN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(11); else result = (PType) log(result); } else serror(10); get_token(); return; case LOG10: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(13); else result = (PType) log10(result); } else serror(12); get_token(); return; case TAN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(15); else result = (PType) tan(result); } else serror(14); get_token(); return; case SQRT: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(17); else result = (PType) sqrt(result); } else serror(16); get_token(); return; case FABS: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(19); else result = (PType) fabs(result); } else serror(18); get_token(); return; case ASIN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(21); else result = (PType) asin(result); } else serror(20); get_token(); return; case ACOS: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(23); else result = (PType) acos(result); } else serror(22); get_token(); return; case ATAN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(25); else result = (PType) atan(result); } else serror(24); get_token(); return; case SINH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(27); else result = (PType) sinh(result); } else serror(26); get_token(); return; case COSH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(29); else result = (PType) cosh(result); } else serror(28); get_token(); return; case TANH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(31); else result = (PType) tanh(result); } else serror(30); get_token(); return; case FACT: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(33); else result = (PType) fact(result); } else serror(32); get_token(); return; case LOG: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(arg1); if ( *token != ',' ) serror(36); else { get_token(); eval_exp2(arg2); if ( *token != ')' ) serror(35); else result = (PType) log10(arg1)/log10(arg2); } } else serror(34); get_token(); return; case FMOD: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(arg1); if ( *token != ',' ) serror(39); else { get_token(); eval_exp2(arg2); if ( *token != ')' ) serror(38); else result = (PType) fmod(arg1,arg2); } } else serror(37); get_token(); return; case CEIL: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(41); else result = (PType) ceil(result); } else serror(40); get_token(); return; case FLOOR: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(43); else result = (PType) floor(result); } else serror(42); get_token(); return; case SECANT: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(45); else result = (PType) 1/cos(result); } else serror(44); get_token(); return; case COSECANT: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(47); else result = (PType) 1/sin(result); } else serror(46); get_token(); return; case COTAN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(49); else result = (PType) 1/tan(result); } else serror(48); get_token(); return; case ASEC: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(51); else result = (PType) atan( result / ((result * result - 1)*(result * result - 1)) ) + signed((result) -1) * (2 * atan((PType)1) ); } else serror(50); get_token(); return; case ACOSEC: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(53); else result = (PType) atan(result / (result * result - 1)*(result * result - 1)) + (signed(result) - 1) * (2 * atan((PType)1)); } else serror(52); get_token(); return; case ACOTAN: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(55); else result = (PType) atan(result) + 2 * atan((PType)1); } else serror(54); get_token(); return; case COSECH:get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(57); else result = (PType) 2/( exp(result) - exp(-result) ); } else serror(56); get_token(); return; case COTANH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(59); else result = (PType) ( exp(result) + exp(-result) ) / ( exp(result) - exp(-result) ); } else serror(58); get_token(); return; case ASINH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(61); else result = (PType) log(result + (result * result + 1)*(result * result + 1)); } else serror(60); get_token(); return; case ACOSH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(63); else result = (PType) log(result + (result * result - 1)*(result * result - 1)); } else serror(62); get_token(); return; case ATANH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(65); else result = (PType) log( (1 + result) / (1 - result) ) / 2; } else serror(64); get_token(); return; case ASECH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(67); else result = (PType) log( ( (-result * result + 1)*(-result * result + 1) + 1 ) / result); } else serror(66); get_token(); return; case ACOSECH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(69); else result = (PType) log((signed(result) * (result * result + 1)*(result * result + 1) +1) / result); } else serror(68); get_token(); return; case ACOTANH: get_token(); if ( *token == '(' ) { get_token(); eval_exp2(result); if ( *token != ')' ) serror(71); else result = (PType) log((result + 1) / (result - 1)) / 2; } else serror(70); get_token(); return; default: serror(0); } default: serror(0); } } template <class PType> void CParser<PType>::putback() { char* t; t = token; for( ; *t; t++) exp_ptr--; } template <class PType> void CParser<PType>::serror(int error) { IsErr = true; static char *e[] = { "Parsing error", "Breake balance of brackets", "Expretion is empty", "Undefine variable", "SIN can't be a variable", "Breake balance of SIN brackets", "COS can't be a variable", "Breake balance of COS brackets", "EXP can't be a variable", "Breake balance of EXP brackets", "LN can't be a variable", "Breake balance of LN brackets", "LOG10 can't be a variable", "Breake balance of LOG10 brackets", "TAN can't be a variable", "Breake balance of TAN brackets", "SQRT can't be a variable", "Breake balance of SQRT brackets", "ABS can't be a variable", "Breake balance of ABS brackets", "ASIN can't be a variable", "Breake balance of ASIN brackets", "ACOS can't be a variable", "Breake balance of ACOS brackets", "ATAN can't be a variable", "Breake balance of ATAN brackets", "SINH can't be a variable", "Breake balance of SINH brackets", "COSH can't be a variable", "Breake balance of COSH brackets", "TANH can't be a variable", "Breake balance of TANH brackets", "FACT can't be a variable", "Breake balance of FACT brackets", "LOG can't be a variable", "Breake balance of LOG brackets", "LOG have two parametrs", "MOD can't be a variable", "Breake balance of MOD brackets", "MOD have two parametrs", "CEIL can't be a variable", "Breake balance of CEIL brackets", "FLOOR can't be a variable", "Breake balance of FLOOR brackets", "SECANT can't be a variable", "Breake balance of SECANT brackets", "COSECANT can't be a variable", "Breake balance of COSECANT brackets", "COTAN can't be a variable", "Breake balance of COTAN brackets", "ASEC can't be a variable", "Breake balance of ASEC brackets", "ACOSEC can't be a variable", "Breake balance of ACOSEC brackets", "ACOTAN can't be a variable", "Breake balance of ACOTAN brackets", "COSECH can't be a variable", "Breake balance of COSECH brackets", "COTANH can't be a variable", "Breake balance of COTANH brackets", "ASINH can't be a variable", "Breake balance of ASINH brackets", "ACOSH can't be a variable", "Breake balance of ACOSH brackets", "ATANH can't be a variable", "Breake balance of ATANH brackets", "ASECH can't be a variable", "Breake balance of ASECH brackets", "ACOSECH can't be a variable", "Breake balance of ACOSECH brackets", "ACOTANH can't be a variable", "Breake balance of ACOTANH brackets", "You can't chage constants" }; cout << e[error] << endl; } template <class PType> void CParser<PType>::get_token() { int i=0; register char* temp; char fun[10] = {0}; tok_type = 0; temp = token; *temp = '\0'; if( !*exp_ptr ) return; while ( isspace(*exp_ptr) ) *exp_ptr++; if ( strchr("+-*/%^=(),:;",*exp_ptr) ) { *temp++ = *exp_ptr++; tok_type = DELIMITER; } else if ( isalpha(*exp_ptr) ) { while ( !isdelim(*exp_ptr) ) { fun[i] = *exp_ptr; *temp++ = *exp_ptr++; i++; } if ( strcmp(fun,"sin") == 0) { tok_type = FUNCTION; fun_type = SIN; } else if ( strcmp(fun,"cos") == 0) { tok_type = FUNCTION; fun_type = COS; } else if ( strcmp(fun,"exp") == 0) { tok_type = FUNCTION; fun_type = EXP; } else if ( strcmp(fun,"ln") == 0) { tok_type = FUNCTION; fun_type = LN; } else if ( strcmp(fun,"log10") == 0) { tok_type = FUNCTION; fun_type = LOG10; } else if ( strcmp(fun,"tan") == 0) { tok_type = FUNCTION; fun_type = TAN; } else if ( strcmp(fun,"sqrt") == 0) { tok_type = FUNCTION; fun_type = SQRT; } else if ( strcmp(fun,"abs") == 0) { tok_type = FUNCTION; fun_type = FABS; } else if ( strcmp(fun,"asin") == 0) { tok_type = FUNCTION; fun_type = ASIN; } else if ( strcmp(fun,"acos") == 0) { tok_type = FUNCTION; fun_type = ACOS; } else if ( strcmp(fun,"atan") == 0) { tok_type = FUNCTION; fun_type = ATAN; } else if ( strcmp(fun,"sinh") == 0) { tok_type = FUNCTION; fun_type = SINH; } else if ( strcmp(fun,"cosh") == 0) { tok_type = FUNCTION; fun_type = COSH; } else if ( strcmp(fun,"tanh") == 0) { tok_type = FUNCTION; fun_type = TANH; } else if ( strcmp(fun,"fact") == 0) { tok_type = FUNCTION; fun_type = FACT; } else if ( strcmp(fun,"log") == 0) { tok_type = FUNCTION; fun_type = LOG; } else if ( strcmp(fun,"mod") == 0) { tok_type = FUNCTION; fun_type = FMOD; } else if ( strcmp(fun,"ceil") == 0) { tok_type = FUNCTION; fun_type = CEIL; } else if ( strcmp(fun,"floor") == 0) { tok_type = FUNCTION; fun_type = FLOOR; } else if ( strcmp(fun,"secant") == 0) { tok_type = FUNCTION; fun_type = SECANT; } else if ( strcmp(fun,"cosecant") == 0) { tok_type = FUNCTION; fun_type = COSECANT; } else if ( strcmp(fun,"cotan") == 0) { tok_type = FUNCTION; fun_type = COTAN; } else if ( strcmp(fun,"asec") == 0) { tok_type = FUNCTION; fun_type = ASEC; } else if ( strcmp(fun,"acosec") == 0) { tok_type = FUNCTION; fun_type = ACOSEC; } else if ( strcmp(fun,"acotan") == 0) { tok_type = FUNCTION; fun_type = ACOTAN; } else if ( strcmp(fun,"cosech") == 0) { tok_type = FUNCTION; fun_type = COSECH; } else if ( strcmp(fun,"cotanh") == 0) { tok_type = FUNCTION; fun_type = COTANH; } else if ( strcmp(fun,"asinh") == 0) { tok_type = FUNCTION; fun_type = ASINH; } else if ( strcmp(fun,"acosh") == 0) { tok_type = FUNCTION; fun_type = ACOSH; } else if ( strcmp(fun,"atanh") == 0) { tok_type = FUNCTION; fun_type = ATANH; } else if ( strcmp(fun,"atanh") == 0) { tok_type = FUNCTION; fun_type = ATANH; } else if ( strcmp(fun,"asech") == 0) { tok_type = FUNCTION; fun_type = ASECH; } else if ( strcmp(fun,"acosech") == 0) { tok_type = FUNCTION; fun_type = ACOSECH; } else if ( strcmp(fun,"acotanh") == 0) { tok_type = FUNCTION; fun_type = ACOTANH; } else { cur_var = fun; tok_type = VARIABLE; } } else if ( isdigit(*exp_ptr) ) { while ( !isdelim(*exp_ptr) ) *temp++ = *exp_ptr++; tok_type = NUMBER; } *temp='\0'; } template <class PType> int CParser<PType>::isdelim(char c) { if ( strchr(" +-/*%^=(),;:",c) || c == 9 || c == '\r' || c == 0) return 1; return 0; } template <class PType> PType CParser<PType>::find_var(string s) { tVr::iterator pos = vars.find(s); if ( pos==vars.end() ) { serror(3); return (PType) 0; } return pos->second; } template <class PType> bool CParser<PType>::IsError() { return IsErr; } template <class PType> tVr CParser<PType>::GetVars() { return vars; } template <class PType> void CParser<PType>::SetValue(string var,PType& value) { vars[var] = value; } template <class PType> PType CParser<PType>::GetValue(string var) { return vars[var]; } #endif |
------- Отправлено: 18:56, 30-09-2010 | #7 |
Новый участник Сообщения: 10
|
Профиль | Отправить PM | Цитировать ganselo
Очень благодарен но ето ООП я в нем не шарю вобще(((( Может какойто код на обичном С |
Отправлено: 00:28, 04-10-2010 | #8 |
![]() Старожил Сообщения: 232
|
Профиль | Сайт | Отправить PM | Цитировать Есть такая книжка Герберт Шилдт "Программирование для профессионалов"(если не ошибаюсь в названии). Вот там подробно описывается алгоритм выше, только на Си.
|
------- Отправлено: 00:41, 04-10-2010 | #9 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
VBA - Задача по информатике | Triz | Программирование и базы данных | 22 | 24-12-2012 23:02 | |
Интересная задача | truvo | Хочу все знать | 9 | 19-07-2010 12:42 | |
C/C++ - Математическая задача | pirojok750 | Программирование и базы данных | 19 | 03-10-2009 12:36 | |
Теория - Задача | ManHack | Программирование и базы данных | 4 | 23-01-2009 18:21 | |
Задача С++ | papam | Программирование и базы данных | 1 | 28-11-2005 11:34 |
|