5
5
Отчёт
Содержание:
1
1. Введение……………………………………………………………………………….. 3
2. Постановка задачи………………………………………………………………… 4
3. Руководство пользователя……………………………………………………. 6
4. Руководство программиста…………………………………………………… 8
5. Заключение……………………………………………………………………………. 12
6. Список литературы………………………………………………………………… 13
7. Приложение…………………………………………………………………………… 14
Введение
2
Стек: определение и принцип работы
Постановка задачи
3
Целью работы является разработка программы для обработки
арифметических выражений с использованием структуры данных стек. В
рамках этой задачи необходимо реализовать два класса: TStack и TArithm.
Класс TStack предназначен для реализации стека и выполнения основных
операций над ним, а класс TArithm – для обработки арифметических
выражений.
4
Добавить функциональность для вывода таблицы соответствия скобок
друг другу.
Реализовать метод Postfix(), который будет взаимодействовать с полем
string infix (строка с арифметическим выражением в инфиксной форме)
и возвращать строку с арифметическим выражением в постфиксной
форме записи.
Реализовать метод Calc(), который будет вычислять и возвращать
результат арифметического выражения в постфиксной форме,
используя стек.
Создать механизм отслеживания ошибок (тип и количество) в
арифметическом выражении, таких как деление на ноль,
несоответствие числа операций числу операндов и несоответствие
скобок друг другу.
Общие требования:
Руководство пользователя
5
Для создания объекта класса TStack необходимо вызвать его конструктор и
присвоить объекту имя.
Случай 1)
Случай 2)
Руководство программиста
7
Класс Стек TStack. Имеет два приватных поля: double* arr (указатель на
память, выделенную для хранения стека) и int top (индекс элемента
массива, в котором хранится последнее добавленное значение стека).
Класс Арифметическое выражение TArithm. Имеет несколько
приватных полей и методов: string infix (строка, содержащая
арифметическое выражение в инфиксной форме), string postfix (строка,
содержащая арифметическое выражение в постфиксной форме),
double res (переменная для хранения результата вычислений
арифметического выражения), int mist_null (счётчик ошибок,
связанных с делением на ноль в арифметическом выражении), int
mist_imbalance (счётчик ошибок, связанных с несоответствием числа
операций числу операндов), int mist_braces (счётчик ошибок,
связанных с несоответствием скобок в арифметическом выражении).
Описание алгоритмов.
TStack:
TArithm:
8
Конструктор инициализации. Принимает строку. Счетчики ошибок
(mist_braces, mist_null, mist_imbalance) становятся равными нулю. В
поле infix сохраняется переданный параметр. Полю postfix
присваивается результат работы метода Postfix(), полю res
присваивается результат работы метода Calc().
int GetPriority(double i). Инициализируется переменная 'p' (приоритет)
значением 0. С помощью if переданный символ 'i' проверяется на
соответствие определенным арифметическим операторам (+, -, *, /).
Если операция является сложением или вычитанием, приоритет
устанавливается в 1. Если операция умножения или деления,
приоритет устанавливается в 2. Возвращается переменная p. Следует
отметить, что переменная ‘i’ типа данных double сравнивается с
переменной типа данных char, используя код соответствующего
символа в таблице ASCII.
bool IsNumber(char i). С помощью if выполняется проверка, равен ли
символ одному из десяти цифровых символов от '0' до '9'. Если символ
соответствует одной из цифр, метод возвращает true, иначе false.
string Postfix(). Создается пустая строка Postfix для хранения
постфиксной формы, а также объект стека. Инициализируются
счетчики left_brace и right_brace для левых и правых скобок
соответственно, а также счетчики num_counter для чисел и op_counter
операторов. Затем с помощью цикла for осуществляется проход по
каждому символу в инфиксной форме:
o Если символ – число (проверяется с помощью метода
IsNumber()), он добавляется к строке Postfix, счетчик чисел
num_counter увеличивается.
o Иначе, если символ - закрывающая скобка, то счётчик правых
скобок right_brace увеличивается на единицу и с помощью цикла
while извлекаются элементы из стека в строку Postfix, пока не
встретится открывающая скобка или пока стек не станет пустым
(проверяется с помощью метода Empty()). Сама же левая скобка
удаляется из стека.
o Иначе, если символ - открывающая скобка, она добавляется в
стек, а счётчик left_brace увеличивается на единицу.
o Иначе (подразумевается, что символ является оператором)
счётчик операторов op_counter увеличивается на единицу и с
9
помощью цикла while извлекаются операторы из стека с таким
же или более высоким приоритетом и добавляются в строку
Postfix. Затем текущий оператор добавляется в стек.
С помощью цикла while и метода Empty() выполняется извлечение
оставшихся операторов из стека и добавление их в строку Postfix.
Проверяется сбалансированность скобок и соответствие числа
операторов числу операндов. Если есть дисбаланс или несоответствие
– счетчик соответствующих ошибок увеличивается на единицу. Затем,
если в выражении есть скобки – вызывается метод Braces(). В конце
метода возвращается строка Postfix.
double Calc(). Создается стек Stack для хранения операндов и
промежуточных результатов. С помощью цикла for осуществляется
проход по каждому символу в постфиксной форме:
o Если символ – число (проверяется с помощью метода
IsNumber()), оно добавляется в стек.
o Иначе (подразумевается, что символ является оператором +, -, *
или /), извлекаются два операнда из стека (метод Get() класса
TStack).
o В зависимости от оператора выполняется соответствующая
операция (+, -, *, /). Стоит отметить, что если операция является
делением, а второй оператор равен нулю, то возвращается ноль
и счётчик ошибок mist_null увеличивается на единицу.
o Результат операции помещается в стек.
После цикла for результат всех вычислений извлекается из стека и
возвращается.
void Braces(). Выражение просматривается посимвольно слева
направо. Все символы, кроме скобок, игнорируются (т.е. просто
производится переход к просмотру следующего символа). Выводится
заголовок таблицы для отображения пар скобок. Инициализируется
переменная counter для отслеживания номера текущей пары скобок.
Создается стек Stack для хранения номеров пар открывающих скобок. С
помощью цикла for осуществляется проход по каждому символу в
инфиксной форме:
o Если символ - открывающая скобка, counter увеличивается на
единицу, и ее номер помещается в стек (метод Put() класса
TStack).
10
o Если символ - закрывающая скобка, увеличивается counter, и с
помощью оператора if проверяется, есть ли соответствующая
открывающая скобка в стеке (метод Empty() класса TStack). Если
есть, выводятся индексы пары скобок. Иначе, выводится
информация о непарной закрывающей скобке, и счетчик ошибок
mist_braces увеличивается.
С помощью цикла while и метода Empty класса TStack проверяется если
в стеке остались открывающие скобки, выводится информация о
непарных скобках, и счетчик ошибок mist_braces увеличивается.
void Output(). Выводится исходное арифметическое выражение.
Выводится постфиксная форма этого выражения. Проверяется наличие
ошибок. Если ошибок нет, выводится результат вычислений. Иначе, на
экран выводятся все типы найденных ошибок.
Заключение
12