| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Вычисление выражений из файла |
| Автор: Linchx 31.7.2011, 17:46 | ||
| Здравствуйте! Суть задачи следующая: необходимо считать из файла выражение и на выходе получить результат его вычисления. Написал программу, за основу взял алгоритм "Обратной польской записи", на вход идет файл с выражением, программа его считывает производит операции арифметические, но не верно. Помогите разобраться с этой задачей.
вот, что подавал на вход: 5+5/2 6+9*7+10*5 5+5/2 итог на выходе: 5+5/2=1 6+9*7+10*5=0 5+5/2=2 |
| Автор: volatile 31.7.2011, 19:07 |
Ну вы хоть бы для виду сначала поинтересовались что такое обратная польская запись. а уж потом писать суровый код... |
| Автор: Teleport 31.7.2011, 19:07 | ||
Гляди комментарии. Условие первого цикла неверно. В общем, смысл тот, что stack еще не содержит тех элементов, которые должны быть считаны из файла, а с ними уже пытаешься проводить операции. |
| Автор: Linchx 31.7.2011, 19:11 | ||||
Да, я понимаю, что вы хотите сказать. Нужно подавать вот в такой форме?
но у меня даже, если так вводить, то выдаст не верный ответ |
| Автор: Linchx 31.7.2011, 19:41 | ||||||||||||
Спасибо, Teleport! Так понятно, что программа считывает изначально 5 потом идущий за ней символ "+" и после 5. Хотя должен на вход получить 5 5 +, только как изначально из инфиксной в постфиксную перевести? Спасибо ещё на счет size_t, теперь понятно на, что жаловался компилятор:
Добавлено через 6 минут и 33 секунды
Да, ошибся извиняюсь:
приоритет перепутал=) |
| Автор: volatile 31.7.2011, 20:04 |
Ну вот видите, ваша программа оказывается делает именно то, что и должна делать. поздравляю! |
| Автор: Teleport 31.7.2011, 20:12 | ||||
Ну вот смотри. В первой итерации у тебя считывается 5 и заносится как stack[ 0 ] m увеличивается на 1 и равно 1 Во второй итерации у тебя считывается '+' и в switch у тебя оператор сложения
получается складывается stack[ 1 - 2 ] + stack [ 1 - 1 ]. В stack[ -1 ] - неизвестно что. Отсюда и надо думать. Либо неправильный алгоритм чтения, либо неправильные данные на вход. |
| Автор: volatile 31.7.2011, 20:21 |
| Teleport, там алгоритм обратной польской записи. подробнее http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C За исключением небольших неточностей (типа сравнения сигнед с ансигнед) программа делает именно то, что и должна делать. |
| Автор: Linchx 31.7.2011, 20:24 | ||||||
Скорее неправильные данные на вход, просто они уже должны быть в "постфиксной форме", а я их по-глупости в "инфиксной форме" ввожу. Сейчас проверил выражение в "постфиксной форме", считает. |
| Автор: Teleport 31.7.2011, 22:37 | ||
| 2 volatile - это мне понятно и вы тоже об этом писали, но я хотел указать именно на то как работает код автора дабы можно было четко увидеть почему идет расчет именно так, а не как положено. А сравнение типов я уже поправил еще в посте номер 3. 2 Linchx - самое важное - понять почему программа работала не так как ожидалось. Вроде, ты все понял
Надо всегда разбираться с ошибками и знать точно - в чем именно каждая ошибка |
| Автор: Linchx 31.7.2011, 23:58 | ||||
Teleport и volatile, спасибо большое! |
| Автор: Linchx 1.8.2011, 04:40 | ||||
Я ещё один вопрос возник. Как можно для входного выражения:
обработать ошибку и пропустить его. Таким образом отбросить не верно составленные выражения. Знаю, что можно при помощи оператора 'continue' пропустить, но условие не могу составить.
а как запретить делить на ноль и ввод не верного арифметического выражения, не имею понятия. |
| Автор: volatile 1.8.2011, 11:12 | ||||
| Не совсем понял откуда вы взяли последний код, Если мои телепатические способности меня не подвели, то вероятно этот код должен вызывать процедуру eval_exp(), которая и вычисляет выражение? Обработку ошибок нужно проводить именно в eval_exp(), и она должна возвращать код ошибки, или 0 если ошибок нет. Обработать ошибку в eval_exp() - просто. например деление на 0
Там же обязательно проверку стека. Ну и много чего еще предусмотреть... Все это надо делать в в eval_exp(); а никак не в общем цикле. |
| Автор: Linchx 1.8.2011, 13:34 | ||||||||||
Спасибо, но я код изменил, теперь считаю инфиксные выражения. Пытаюсь присвоить переменной answer значение sn в случае ошибки она бы выводила сигнал, чтобы увидеть надпись wrong example, выводит но надпись "nan". Как можно изменить эту надпись? Может кто встречался с подобным!?
в syntax.cpp передается prog и answer, так же в syntax.cpp объявлено, что в случае недопустимых операций и арифметических выражений возвращать NaN для типа double. Но вот почему он вместо can't calculate записывает nan непонятно.
|
| Автор: Linchx 1.8.2011, 15:31 | ||||||||||
Решил проблему, видно неправильно сравнивал условие: было:
поменял:
|