|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Ввод формул |
|
C/C++ - Ввод формул
|
Пользователь Сообщения: 69 |
Допустим надо ввести в консоль пример (2+2) , чтоб прога его посчитала. Как можно это реализовать?
|
|
Отправлено: 00:20, 03-11-2009 |
Необычный Сообщения: 4464
|
Профиль | Сайт | Отправить PM | Цитировать Doom77,
Цитата Doom77:
Гляньте в сторону Обратной Польской Записи. |
|
------- Отправлено: 08:12, 03-11-2009 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
![]() Ветеран Сообщения: 1180
|
Профиль | Отправить 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 |
Пользователь Сообщения: 69
|
Профиль | Отправить 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 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать Уже разобрался )
|
|
Отправлено: 10:45, 04-11-2009 | #5 |
Пользователь Сообщения: 69
|
Профиль | Отправить 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 |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать Мне нужно будет провести несколько операций с введенной формулой. Как ее сохранить?
|
Отправлено: 21:25, 04-11-2009 | #7 |
Необычный Сообщения: 4464
|
Профиль | Сайт | Отправить PM | Цитировать Doom77, распиши пожалуйста в Формах_Бэкуса_—_Наура
так проще просматривать структуру программы. И расставь пожалуйста комментарии, т.к. для реализаций задумки есть множество алгоритмов. Или словами ход действий расскажи. |
------- Отправлено: 00:49, 05-11-2009 | #8 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Глюки редакторе формул | 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 |
|