Ю12.31

Задача: строка содержит арифметическое выражение, состоящее из целых чисел и знаков операции: [latex]+,-,*,/[/latex]  (без скобок). Проверить корректность выражения (в смысле последовательности чисел и знаков операции)

Тесты: 

Выражение Ответ Комментарий
-1+2-3/4*5 Верно Работает
-1 Верно Работает
-1/-4 Верно Работает
5—4 Верно Работает
1 Верно Работает
54-*3//6 Ошибка Работает. Неправильная последовательность
5/0+42 Ошибка Работает. Деление на ноль
5/ Ошибка Работает. После символа должно следовать число

Объяснение переменных:

string a  — строка для ввода.

bool rightness  — булева переменная для фиксирования ошибочного выражения.

Код:  Проверить на ideone.

Алгоритм выполнения описан в комментариях в коде.

 

Особенности:

  1. Удобно предположить, что изначально выражение верно. И в случае отсутствия ошибок, переменной rightness присваивать ничего не нужно будет.

Итог работы:

Код проверяет правильность выражения (последовательность чисел и знаков) с учётом унарного минуса (но не плюса)*, так-же за ошибку считается деление на ноль. Примеры применения есть в тестах.

* — легко реализовать посредством удаления a[0] == '+' из соответствующих if’ах, но не стал, так как считаю унарный плюс бессмысленным.

Related Images:

10 thoughts on “Ю12.31

  1. С выражениями вида a.length()-1, a.length() — 2 нужно быть поосторожнее, т.к. не исключается, что длина строки будет небольшой, или даже 0 символов. Ситуацию усугубляет факт, что значение a.length() — беззнаковое. См. http://ideone.com/o4wJdk .

    Еще один интересный момент: допускаете ли Вы унарный минус и плюс, т.е. корректно ли выражение 3+-1, или 5*-3, или совсем безобидное -3+2? Обычно такие выражения вполне допускаются — минус или плюс является унарным, если следует после символа операции (или вначале строки).

    Кстати, переменную b можно было сделать логической (bool).

    • Спасибо за замечания.

      По поводу a.length(). По условию задачи предусматривается, что выражение имеет И целое число И знак. Следовательно можно этого не боятся. Тем более что теперь a.length()-1, а не a.length()-2, т.к. я решил ещё проверять «/0».

      Плюс допускать я считаю бессмысленным, он в любом случае опускается. А по поводу минуса соглашусь. Исправил.

      b сделал логической и переименовал на rightness.

  2. Отлично пусть будет rightness, только тогда лучше

    Т.е. переменная булева — а при выводе мы генерируем хорошее читаемое для пользователя сообщение — это лучше всего. А то так как сейчас непонятно.

    это деление на ноль проверяется? Тогда лучше так и указать «случай деления на 0 (/0)».

    Удивительно, что сейчас последний знак теперь у Вас не проверяется и, например, «5-» у Вас правильное выражение.

    • Спасибо за замечания. Исправил.

  3. Во первых, Вы не обновили программу на ideone.

    Ну а во вторых… «Т.к. в самом начале мы проверяем первый символ, то в цикле не логично проверять его ещё раз.» — очень опасное и коварное рассуждение … вроде бы все верно, по крайней мере в изначальном варианте так и было … потом оказывается, что со знака минус выражение может начинаться — убираем минус из проверки первого символа, ОК, но теперь -*5 это правильное выражение! Как так? А ведь мы не проверяем сочетание первого символа со вторым — первый ведь же проверен.

    • Готово. Теперь я просто проверяю первый и последний символы, и заодно проверяю всю строку. Для надёжности. Должно работать

  4. После первого if не хватает else — наверное, изначально он был, но потерялся в процессе переделки — по логике он быть должен, особенно учитывая комментарий // если всё верно (в начале и в конце стоят не знаки), то выполняется цикл,

    Теперь по отчету — понимаю, что краткость сестра таланта, но сейчас он явно неполный. Ведь мы с Вами проговорили столько нетривиальных моментов — но, увы, они отражены только в комментариях к записи, ну и частично в комментариях к программе. А должны быть в отчете тоже. Самое главное чего не хватает — четкой формулировки, какие выражения Вы считаете правильными, а какие нет. Без этого из отчета непонятно, какую конкретно задачу Вы решали (ну или каким конкретно способом в другой формулировке).

    • Да, там сначала был else if, спасибо.

      Дополнил отчёт.

  5. Засчитано, 7 баллов.

    for (int i = 0; (i < a.length()); i++) потом a[i+1] плохо! выход за пределы строки 1 Ошибка Работает. Должены быть и число и символ (по условию) Ваша программа выдает Верно . Я считаю, что программа работает правильно и одно число тоже является выражением — но в отчете у Вас написано не так — и хуже того Вы обманываете нас, в том что тест пройден.

    Также никак не учтен случай пустой строки, но это уж ладно.

    Вы проделали большую работу и программа нормальная — старайтесь аккуратнее подходить к выполнению задачи и подготовке отчета. Например, если Вы изменили программу Вы должны перепроверить все! тесты (во втором семестре мы устраним это неудобство при помощи технологии автоматического модульного тестирования) и переписать объяснение в отчете — понимаю, что это нудно, долго и неинтересно — но и мне приходится проверять отчет, программу, еще и запускать тесты — которые студенты поленились запустить — поверьте это занимает кучу времени.

    • Спасибо большое. Ранние версии кода на «1» выдавали «ошибку», я над этим не работал, следовательно и проверять не стал. Забавно вышло) Будет хороший опыт. Отчет отредактирую.

Добавить комментарий