вычисление арифметических выражений
От: Аноним  
Дата: 27.04.06 07:22
Оценка:
Где найти готовые библиотеки по разбору строки, содержащей арифметические выражения (типа такого f*(a+b*(d-1/f)) )?
Ну или алгоритм их разборки.
Re: вычисление арифметических выражений
От: DioNNis http://i-liger.com
Дата: 01.05.06 04:27
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Где найти готовые библиотеки по разбору строки, содержащей арифметические выражения (типа такого f*(a+b*(d-1/f)) )?

А>Ну или алгоритм их разборки.

Лично я таких библиотек не встречал и чтот то сомневаюсь, что ини существуют.
У меня вот какое предложение:
берешь каждый символ и анализируешь его при помощи конструкции
switch ()
{
case
}.

что бы взять символ:
string str; — //строка, в которой содержится уравнение
for (int i=0; i<str.length;i++)
{
....= st[i];
}
Владея информацией, владеешь миром. Уинстон Черчилль
Re[2]: вычисление арифметических выражений
От: DioNNis http://i-liger.com
Дата: 01.05.06 04:29
Оценка:
P.S. Весь код написал для С#, но на других языках похоже будет....
Владея информацией, владеешь миром. Уинстон Черчилль
Re: вычисление арифметических выражений
От: Reunion  
Дата: 01.05.06 05:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Где найти готовые библиотеки по разбору строки, содержащей арифметические выражения (типа такого f*(a+b*(d-1/f)) )?

А>Ну или алгоритм их разборки.

В "Книге Дракона" (по компиляторам) кажется в первой главе есть исходник со всеми объяснениями. Книгу точно можно найти в электронном виде. (Ахо, Сети и еще кто-то — авторы)
Re: вычисление арифметических выражений
От: Аноним  
Дата: 02.05.06 09:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Где найти готовые библиотеки по разбору строки, содержащей арифметические выражения (типа такого f*(a+b*(d-1/f)) )?

А>Ну или алгоритм их разборки.

Удобней использовать обратную польскую запись
http://trubetskoy1.narod.ru/ppn.html
Re: вычисление арифметических выражений
От: Nikolaus Россия  
Дата: 06.05.06 06:45
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Где найти готовые библиотеки по разбору строки, содержащей арифметические выражения (типа такого f*(a+b*(d-1/f)) )?

А>Ну или алгоритм их разборки.

Разборка ведется рекурсивно.
Находишь знак операции не в скобках и рекурсивно отдаешь обе части выражения на разбор, к результатам применяешь операцию и выдаешь ответ рекурсивно наверх.
... << Rsdn@Home 1.1.4 beta 1 >>
Re: вычисление арифметических выражений
От: mukhomor  
Дата: 06.05.06 17:10
Оценка:
а-ля синтаксический анализатор от Шилдта.

// A generic parser.

#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
using namespace std;

enum types { DELIMITER = 1, VARIABLE, NUMBER};

const int NUMVARS = 26;

template <class PType> class parser {
  char *exp_ptr;  // points to the expression
  char token[80]; // holds current token
  char tok_type;  // holds token's type
  PType vars[NUMVARS]; // holds variable's values

  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(char *s);
  int isdelim(char c);
public:
  parser();
  PType eval_exp(char *exp);
};

// parser constructor
template <class PType> parser<PType>::parser()
{
  int i;

  exp_ptr = NULL;
 
  for(i=0; i<NUMVARS; i++) vars[i] = (PType) 0;
}

// Parser entry point.
template <class PType> PType parser<PType>::eval_exp(char *exp)
{
  PType result;

  exp_ptr = exp;

  get_token();
  if(!*token) {
    serror(2); // no expression present
    return (PType) 0;
  }
  eval_exp1(result);
  if(*token) serror(0); // last token must be null
  return result;
}

// Process an assignment.
template <class PType> void parser<PType>::eval_exp1(PType &result)
{
  int slot;
  char ttok_type;
  char temp_token[80];

  if(tok_type==VARIABLE) {
    // save old token
    strcpy(temp_token, token);
    ttok_type = tok_type;

    // compute the index of the variable
    slot = toupper(*token) - 'A';

    get_token();
    if(*token != '=') {
      putback(); // return current token
      // restore old token - not assignment
      strcpy(token, temp_token);
      tok_type = ttok_type;
    }
    else {
      get_token(); // get next part of exp
      eval_exp2(result);
      vars[slot] = result;
      return;
    }
  }

  eval_exp2(result);
}

// Add or subtract two terms.
template <class PType> void parser<PType>::eval_exp2(PType &result)
{
  register char op;
  PType temp;

  eval_exp3(result);
  while((op = *token) == '+' || op == '-') {
    get_token();
    eval_exp3(temp);
    switch(op) {
      case '-':
        result = result - temp;
        break;
      case '+':
        result = result + temp;
        break;
    }
  }
}

// Multiply or divide two factors.
template <class PType> void parser<PType>::eval_exp3(PType &result)
{
  register char op;
  PType temp;

  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;
    }
  }
}

// Process an exponent
template <class PType> void parser<PType>::eval_exp4(PType &result)
{
  PType temp, ex;
  register int t;

  eval_exp5(result);
  if(*token== '^') {
    get_token();
    eval_exp4(temp);
    ex = result;
    if(temp==0.0) {
      result = (PType) 1;
      return;
    }
    for(t=(int)temp-1; t>0; --t) result = result * ex;
  }
}

// Evaluate a unary + or -.
template <class PType> void parser<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;
}

// Process a parenthesized expression.
template <class PType> void parser<PType>::eval_exp6(PType &result)
{
  if((*token == '(')) {
    get_token();
    eval_exp2(result);
    if(*token != ')')
      serror(1);
    get_token();
  }
  else atom(result);
}

// Get the value of a number or a variable.
template <class PType> void parser<PType>::atom(PType &result)
{
  switch(tok_type) {
    case VARIABLE:
      result = find_var(token);
      get_token();
      return;
    case NUMBER:
      result = (PType) atof(token);
      get_token();
      return;
    default:
      serror(0);
  }
}

// Return a token to the input stream.
template <class PType> void parser<PType>::putback()
{
  char *t;

  t = token;
  for(; *t; t++) exp_ptr--;
}

// Display a syntax error.
template <class PType> void parser<PType>::serror(int error)
{
  static char *e[]= {
      "Syntax Error",
      "Unbalanced Parentheses",
      "No expression Present"
  };
  cout << e[error] << endl;
}

// Obtain the next token.
template <class PType> void parser<PType>::get_token()
{
  register char *temp;

  tok_type = 0;
  temp = token;
  *temp = '\0';

  if(!*exp_ptr) return; // at end of expression

  while(isspace(*exp_ptr)) ++exp_ptr; // skip over white space

  if(strchr("+-*/%^=()", *exp_ptr)){
    tok_type = DELIMITER;
    // advance to next char
    *temp++ = *exp_ptr++;
  }
  else if(isalpha(*exp_ptr)) {
    while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++;
    tok_type = VARIABLE;
  }
  else if(isdigit(*exp_ptr)) {
    while(!isdelim(*exp_ptr)) *temp++ = *exp_ptr++;
    tok_type = NUMBER;
  }

  *temp = '\0';
}

// Return true if c is a delimiter.
template <class PType> int parser<PType>::isdelim(char c)
{
  if(strchr(" +-/*%^=()", c) || c==9 || c=='\r' || c==0)
    return 1;
  return 0;
}

// Return the value of a variable.
template <class PType> PType parser<PType>::find_var(char *s)
{
  if(!isalpha(*s)){
    serror(1);
    return (PType) 0;
  }
  return vars[toupper(*token)-'A'];
}



Демонстрация.

int main()
{
  char expstr[80];

  // Demonstrate floating-point parser.
  parser<double> ob;

  cout << "Floating-point parser.  ";
  cout << "Enter a period to stop\n";
  for(;;) {
    cout << "Enter expression: ";
    cin.getline(expstr, 79);
    if(*expstr=='.') break;
    cout << "Answer is: " << ob.eval_exp(expstr) << "\n\n";
  }
  cout << endl;

  // Demonstrate integer-based parser.
  parser<int> Iob;

  cout << "Integer parser.  ";
  cout << "Enter a period to stop\n";
  for(;;) {
    cout << "Enter expression: ";
    cin.getline(expstr, 79);
    if(*expstr=='.') break;
    cout << "Answer is: " << Iob.eval_exp(expstr) << "\n\n";
  }

  return 0; 
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.