Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Ввод формул

Ответить
Настройки темы
C/C++ - Ввод формул

Аватара для Doom77

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Допустим надо ввести в консоль пример (2+2) , чтоб прога его посчитала. Как можно это реализовать?

Отправлено: 00:20, 03-11-2009

 

Аватара для lxa85

Необычный


Contributor


Сообщения: 4464
Благодарности: 994

Профиль | Сайт | Отправить PM | Цитировать


Doom77,
Цитата Doom77:
Как можно это реализовать? »
Синтаксическим разбором строки.
Гляньте в сторону Обратной Польской Записи.

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)

Это сообщение посчитали полезным следующие участники:

Отправлено: 08:12, 03-11-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


обычно делается так: считывается символ, по нему решается, какой тип выражения идёт дальше. Если может быть несколько вариантов, то последующие символы считываются и запоминаются до тех пор, пока не будет точно ясно, что вариант единственный. В данном случае:
1. скобки "(" считаем, что могут встретиться варианты 1,2,3,4
2. закрывающаяся скобка ")" выходим из скобки
3. число "+", "-" заталкиваем считанный символ обратно в поток и читаем поток как число, далее возможны только варианты 2,5
4. число "0"-"9" заталкиваем считанный символ обратно в поток и читаем поток как число, далее возможны только варианты 2,5
5. операции "+", "-", "*", "/ " запоминаем операцию, после этого читаем число, далее вариант 4

в начале выражения возможны варианты 1,3,4

Чтобы правильно вычислить выражение, его лучше преобразовать в так называемую польскую запись. Если вычислять выражение во время разбора с учётом приоритетов операций во время разбора, польская запись получится сама собой (даже не придётся над ней думать). При этом типичный прототип функции писать в виде double operation(istream&), например
Код: Выделить весь код
double op_plus(istream&);
double op_minus(istream&);
double op_mul(istream&);
double op_div(istream&);
double op_any_value(istream&);

// тогда можно будет записать например
double op_mul(istream& stm)
{
    return op_any_value(stm) * op_any_value(stm);
}
Приоритеты операций: "(", "*", "/", "+", "-"

Пробуйте, пишите, что получилось
Это сообщение посчитали полезным следующие участники:

Отправлено: 08:27, 03-11-2009 | #3


Аватара для Doom77

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вот нашел пример ввода пытаюсь добавить функцию sin получаеться только не в нутри примера. Где ошибка? Вместо sin надо вводить , ))))))))))))))))))

Код: Выделить весь код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <assert.h>

int tok;
int b=2;
double tokval, x;

int next() {
    for (;;) {
        int c = getchar();
		if (c == EOF || strchr(",+-*/^()\n", c) != NULL) return tok = c;
		
		if (isspace(c)) continue;
        if (isdigit(c) || c == '.') {
            ungetc(c, stdin);
            scanf(" %lf", &tokval);
            return tok = 'n';
        }
        fprintf(stderr, "Bad character: %c\n", c); abort();
    }
}

void skip(int t) { assert(tok == t); next(); }

double expr();

// numpar ::= number | '(' expr ')'
double numpar() {
    if (tok == 'n') { double x = tokval; skip('n'); return x; }
    skip('('); double x = expr(); skip(')'); return x;
}

// factor ::= numpar | numpar '^' factor
double factor() {
    double x = numpar();
    if (tok == '^') { skip('^'); x = pow(x, factor()); }
    return x;
}

// term ::= factor | term '*' factor | term '/' factor
double term() {
    double x = factor();
    for (;;) {
        if (tok == '*') { skip('*'); x *= factor(); }
        else if (tok == '/') { skip('/'); x /= factor(); }
        else return x;
    }
}

// expr ::= term | expr '+' term | expr '-' term
double expr() {
    double x = term();
    for (;;) {
        if (tok == '+') { skip('+'); x += term(); }
        else if (tok == '-') { skip('-'); x -= term(); }
        else return x;
    }
}
double sinn(){
	double x= expr();
	for(;;){
	
		if (tok == ',') { skip(','); x = sin(expr());}
		return x;
	}}

int main() {
    next();
    while (tok != EOF) {
        if (tok == '\n') { skip('\n'); continue; }
        printf("%.9g\n", sinn());
    }
    return 0;
}

Последний раз редактировалось Drongo, 04-11-2009 в 16:08. Причина: [code] - #


Отправлено: 21:34, 03-11-2009 | #4


Аватара для Doom77

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Уже разобрался )

Отправлено: 10:45, 04-11-2009 | #5


Аватара для Doom77

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вот вроде работает. Не выполняет таких действий 2+(-3) как можно сделать?

Код: Выделить весь код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <assert.h>
#include <iostream>

int tok;
int flag;
double b, a,m, n, h, h0, f,y,i, t;
double tokval, x;

int next() {
    for (;;) {
        int c = getchar();
		if (c == EOF || strchr("kws+-*/^()\n", c) != NULL) return tok = c;
		//if (strchr("m",c)) c=a+'0'; 
		if (isspace(c)) continue;
		if (isdigit(c) || c == '.'|| c=='v'|| c=='s'|| c=='w'|| c=='k'|| c=='m') {
            ungetc(c, stdin);
            scanf(" %lf", &tokval);
            return tok = 'n';
        }
        fprintf(stderr, "Bad character: %c\n", c); abort();
    }
}

void skip(int t) { assert(tok == t); next(); }

double kor();

// numpar ::= number | '(' expr ')'
double numpar() {
    if (tok == 'n') { double x = tokval; skip('n'); return x; }
    skip('('); double x = kor(); skip(')'); return x;
}

// factor ::= numpar | numpar '^' factor
double factor() {
    double x = numpar();
    if (tok == '^') { skip('^'); x = pow(x, factor()); }
    return x;
}

// term ::= factor | term '*' factor | term '/' factor
double term() {
    double x = factor();
    for (;;) {
        if (tok == '*') { skip('*'); x *= factor(); }
        else if (tok == '/') { skip('/'); x /= factor(); }
        else return x;
    }
}

// expr ::= term | expr '+' term | expr '-' term
double expr() {
    double x = term();
    for (;;) {
        if (tok == '+') { skip('+'); x += term(); }
        else if (tok == '-') { skip('-'); x -= term(); }
        else return x;
    }
}
double sinn(){
	double x= expr();
	for(;;){
	
		if (tok == 's') { skip('s'); x = sin(expr());}
		return x;
	}
}

double coss(){
	double x= sinn();
	for(;;){
	
		if (tok == 'w') { skip('w'); x = cos(sinn());}
		return x;
	}
}
double kor() {
    double x = coss();
    if (tok == 'k') { skip('k'); x = sqrt(coss()); }
    return x;
}

int main() {
next();
while (tok != EOF) {
if (tok == '\n') { skip('\n'); continue; }
printf("%.9g\n", kor());
}
return 0;
}

Последний раз редактировалось Drongo, 04-11-2009 в 16:09. Причина: Тег [code] на панельке значок - #


Отправлено: 13:32, 04-11-2009 | #6


Аватара для Doom77

Пользователь


Сообщения: 69
Благодарности: 0

Профиль | Отправить PM | Цитировать


Мне нужно будет провести несколько операций с введенной формулой. Как ее сохранить?

Отправлено: 21:25, 04-11-2009 | #7


Аватара для lxa85

Необычный


Contributor


Сообщения: 4464
Благодарности: 994

Профиль | Сайт | Отправить PM | Цитировать


Doom77, распиши пожалуйста в Формах_Бэкуса_—_Наура
так проще просматривать структуру программы.
И расставь пожалуйста комментарии, т.к. для реализаций задумки есть множество алгоритмов.
Или словами ход действий расскажи.

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)


Отправлено: 00:49, 05-11-2009 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Ввод формул

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Глюки  редакторе формул Mishenka Программное обеспечение Windows 11 20-12-2007 01:15
Распознавание формул. BlackEric Хочу все знать 1 05-06-2006 01:52
Delphi - Delphi | Отображение математических формул Ilsha sh Программирование и базы данных 2 31-07-2005 20:32
вставка формул в экселе макросом? Naug Программирование и базы данных 2 22-09-2004 15:47
Delphi - Delphi интерпретатор формул Roman Go Программирование и базы данных 1 26-07-2003 20:12




 
Переход