Сложение и вычитание

Пусть дано выражение, в котором кроме чисел разрешены только знаки «плюс» и «минус»

Рассмотрим на этом примере работу функции evaluate_expression().

В данном случае схема алгоритма довольно тривиальна:

1. возьмем первую лексему; она обязательно будет числом. Запишем это число в current_result.

2. Возьмем следующую лексему. Формально, выражение из единственного числа является корректным, поэтому уже в этот момент текущая лексема может получить тип LT_END. На случай, если в выражении все-таки что-то осталось организуем цикл:

3. Цикл: пока текущая лексема не является LT_END

3.1. Поскольку мы попали в цикл, то после числа стоит не конец строки, а какой -то знак.

3.2. Если текущая лексема LT_PLUS, то
Взять следующую лексему. Это обязательно будет число, его значение попадет в переменную current_lexem_value
current_result = current_result + current_lexem_value

3.2. Если текущая лексема LT_MINUS, то действия аналогичны предыдущему варианту:
Взять следующую лексему. Это обязательно будет число, его значение будет храниться в переменной current_lexem_value
current_result = current_resultcurrent_lexem_value

4. Как только строка закончена, вернуть значение current_result.

Пример функции на языке C.

int evaluate_expression() { void calc_plus() { // в эту функцию мы попадем, только если текущая лексема - это знак "плюс" // при корректных исходных данных логично ожидать после знака "плюс" некоторое число // получим число и обработаем его get_next_lexem(); // здесь можно вставить проверку того, что за плюсом действительно идет число current_result = current_result + current_lexem_value; get_next_lexem(); } int void_minus() { get_next_lexem(); // здесь можно вставить проверку того, что за минусом действительно идет число current_result = current_result - current_lexem_value; get_next_lexem(); } int current_result = 0; get_next_lexem(); // если бы мы не верили в корректность исходных данных, // здесь можно было бы поставить проверку на то, // начинается ли выражение с числа или нет // if (current_lexem_type != LT_NUMBER) {обработка ошибки} // так же, можно сразу отсечь случай пустого выражения на входе // if (current_lexem_type == LT_END) {обработка еще одной ошибки} current_result = current_lexem_value; get_next_lexem(); // берем лексему, следующую за числом // если за числом сразу следует конец строки, то в цикл мы не попадем while (current_lexem_type != LT_END) { // раз мы попали в цикл - ожидаем, что // выражение продолжится корректно, то есть // если после первого числа что-то есть, то это обязательно // знак операции, а потом еще и число // но если в задаче это явно не сказано, то // if ((current_lexem_type != LT_PLUS) && (current_lexem_type != LT_MINUS)) {обработка ошибки} if (current_lexem_type == LT_PLUS) { calc_plus(); } else { calc_minus(); } } // После того, как мы разобрали всю строку – вернем результат return (current_result); }

Функции calc_plus() и calc_minus() возможно, выглядят пока слишком простыми, чтобы оформить их отдельными функциями, но позже за знаками "плюс" и "минус" будут следовать не только числа, но и выражения в скобках, или выражения, состоящие из произведений (например: 5+9*6*(3+1) ). В этом случае функциям обработки "плюса" или "минуса" придется уже значительно потрудиться.

Последнее изменение: Суббота, 15 Август 2020, 02:35