Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Разбор математического выражения

92K
09 января 2014 года
Валерий Есипенко
1 / / 09.01.2014
Код:
float number()
{
    int res = 0;
    for (;;)
    {
        char c = cin.get();
        if (c >= '0' && c <= '9')
            res = res * 10 + c - '0';
        else
        {
            cin.putback(c);
            break;
        }
    }
    return res;
}

float expr();

float func()
{
    struct FuncList
    {
        const char *n; // name
        float (*f)(float); // function
    };
    const FuncList funcList[] =
    {
        { "cos", cos },
        { "sin", sin },
        { "tan", tan },
        { "acos", acos },
        { "asin", asin },
        { "atan", atan },
        { "cosh", cosh },
        { "sinh", sinh },
        { "tanh", tanh },
        { "exp", exp },
        { "log", log },
        { "sqrt", sqrt },
        { "ceil", ceil },
        { "fabs", fabs },
        { "floor", floor },
        { 0, 0 }
    };
    float res;
    string name;
    for (;;)
    {
        char c = cin.get();
        if (c >= 'a' && c <= 'z')
            name += c;
        else
        {
            cin.putback(c);
            break;
        }
    }
    res = expr();
    for (const FuncList *i = funcList; i -> n != 0; ++i)
    {
        if (i -> n == name)
            return i -> f(res);
    }
    cerr << "Неизвестная функция: " << name << endl;
    return res;
}

float hiLevel()
{
    float x;
    char c = cin.get();
    if (c == '(')
    {
        x = expr();
        cin.get();
    }
    else
    {
        cin.putback(c);
        if (isdigit(c))
            x = number();
        else
            x = func();
    }
    return x;
}

float factor()
{
    float x = hiLevel();
    while (true)
    {
        char c = cin.get();
        switch (c)
        {
        case '*':
            x *= hiLevel();
            break;
        case '/':
            x /= factor();
            break;
        default:
            cin.putback(c);
            return x;
        }
    }
}

float expr(char str[], int size)
{
    int i=0;
    float x = factor();
        while(i < size)
        {
            char c = str[i];
            switch (c)
            {
            case '+':
                x += factor();
                break;
            case '-':
                x -= factor();
                break;
            default:
                cin.putback(c);
                return x;
            }
            i++;
    }
}
Есть вот такой простенький математический парсер. Вот надо сделать так, чтобы он умел отлавливать переменные в функции, хотя бы одну, например <x> и присваивать ей какое-то значение. Уже всё, по моему перепробовал, а в ответ получаю только вылеты программы :( Подскажите, что можно придумать. Я не прошу писать код за меня, просто подсказать, как это можно реализовать. Заранее спасибо!
11K
13 января 2014 года
xAtom
65 / / 17.01.2011
Не вижу больших проблем, так же парсируй переменные isalnum как и float после
парсирования переменных находи значение переменной по имени в связном списке или массиве, или в хэш таблице,
или skip-list, rand-tree, splay-tree, rb-tree, avl-tree то есть в любой структуре данных которую реализуешь уникальную ассоциативность, если нет такой переменной выводи сообщение is not found или добавь её со значением 0.

 
Код:
/*  структура данных должна хранить элемент состоящий из ключа где key уникальное название переменной, value значение   переменной. */
typedef struct _var {
     char  key[32];
     float value;
} var;
Цитата:
float number()


Самописная это хорошо но не учитываешь точку или запятую по местной локали и т.п, а если число будет в
экспоненциальной форме записи? ещё переполнение нужно учитывать, лучше использовать strtod или sscanf.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог