- •Часть 2
- •Содержание
- •Задание № Доп-1. Обработка двухмерных динамических массивов. Функции пользователя
- •Особенности применения указателей
- •Связь указателей с массивами
- •Декларация многомерного массива:
- •Указатели на указатели
- •Динамическое размещение данных
- •Минимальный набор действий, необходимых для динамического размещения одномерного массива действительных чисел размером n:
- •Минимальный набор действий, необходимых для динамического размещения двухмерного массива действительных чисел размером nm:
- •Задание №1. Рекурсивные функции
- •1.1. Краткие теоретические сведения
- •1.2. Пример выполнения задания
- •1.2.1. Реализация задания в оконном приложении
- •1.2.2. Реализация задания в консольном приложении
- •1.3. Индивидуальные задания
- •Задание №2. Динамическая структура стек
- •2.1. Краткие теоретические сведения
- •2.2. Пример выполнения задания
- •2.2.1. Реализация задания в оконном приложении
- •2.2.2. Реализация задания в консольном приложении
- •2.3. Индивидуальные задания
- •Задание №3. Динамическая структура очередь
- •3.1. Краткие теоретические сведения
- •Создание первого элемента
- •Добавление элемента
- •Просмотр списка
- •Алгоритм удаления элемента в списке по ключу
- •3.2. Пример выполнения задания
- •3.2.1. Реализация задания в оконном приложении
- •3.2.2. Реализация задания в консольном приложении
- •3.3. Индивидуальные задания
- •Задание №4. Обратная польская запись
- •4.1. Краткие теоретические сведения
- •4.2. Пример выполнения задания
- •4.3. Индивидуальные задания
- •Задание №5. Нелинейные списки
- •5.1. Краткие теоретические сведения
- •Функция просмотра элементов дерева
- •Функция освобождения памяти, занятой деревом
- •5.2. Пример выполнения задания
- •5.3. Индивидуальные задания
- •Задание №6. Алгоритмы поиска корней уравнений
- •6.1. Краткие теоретические сведения
- •Метод простой итерации
- •Метод Ньютона (метод касательных)
- •Метод секущих
- •Метод Вегстейна
- •Метод деления отрезка пополам
- •6.2. Пример выполнения задания
- •6.3. Индивидуальные задания
- •Задание №7. Аппроксимация функций
- •7.1. Краткие теоретические сведения
- •Интерполяционный многочлен Ньютона
- •Линейная и квадратичная интерполяции
- •Интерполяционный многочлен Лагранжа
- •7.2. Пример выполнения задания
- •7.3. Индивидуальные задания
- •Задание №8. Алгоритмы вычисления интегралов
- •8.1. Краткие теоретические сведения
- •Формула средних
- •Формула трапеций
- •Формула Симпсона
- •8.2. Пример выполнения задания
- •8.3. Индивидуальные задания
- •Задание №9. Алгоритмы поиска и сортировки в массивах
- •9.1. Краткие теоретические сведения
- •9.1.1. Алгоритмы поиска
- •Функция поиска всех элементов целочисленного динамического массива а размера n, равных значению х, может иметь следующий вид:
- •Функция поиска одного значения х в целочисленном динамическом массиве а размера n может иметь следующий вид:
- •Else // Вывод сообщения, что элемент не найден
- •9.1.2. Алгоритмы сортировки
- •Функция сортировки элементов целочисленного динамического массива а размера n может иметь следующий вид:
- •Функция сортировки элементов целочисленного динамического массива а размера n может иметь следующий вид:
- •Рекурсивная функция сортировки элементов целочисленного динамического массива а размера n может иметь следующий вид (begin – первый элемент массива, end – последний элемент массива):
- •9.2. Индивидуальные задания
- •Литература
- •Учебное издание
- •Часть 2
- •220013, Минск, п. Бровки, 6
4.2. Пример выполнения задания
Написать программу расшифровки и вычисления арифметических выражений с использованием стека.
Вид формы и полученные результаты представлены на рис. 4.1.
Приведем только тексты используемых функций-обработчиков и созданных функций пользователя (тексты функций InStack и OutStack взять в лаб. работе № 2, заменив тип int на char):
. . .
struct Stack {
char info;
Stack *next;
} *begin;
int Prior (char);
Stack* InStack( Stack*,char);
Stack* OutStack( Stack*,char*);
double Rezult(String);
double mas[201]; // Массив для вычисления
Set <char, 0, 255> znak; // Множество символов-знаков
int Kol = 8;
//--------------------- Текст функции-обработчика FormCreate --------------------------
Edit1->Text = "a+b*(c-d)/e"; Edit2->Text = "";
char a = 'a';
StringGrid1->Cells[0][0] ="Имя"; StringGrid1->Cells[1][0] ="Знач.";
for(int i = 1; i<Kol; i++) {
StringGrid1->Cells[0][i] = a++; StringGrid1->Cells[1][i] = i;
}
//---------------------- Текст функции-обработчика кнопки Перевести ----------------
Stack *t;
begin = NULL; // Стек операций пуст
char ss, a;
String InStr, OutStr; // Входная и выходная строки
OutStr = ""; Edit2->Text = "";
InStr = Edit1->Text;
znak << '*' << '/' << '+' << '-' << '^';
int len = InStr.Length(), k;
for (k = 1; k <= len; k++) {
ss = InStr[k];
// Открывающую скобку записываем в стек
if ( ss == '(' ) begin = InStack(begin, ss);
if ( ss == ')' ) {
// Выталкиваем из стека все знаки операций до открывающей скобки
while ( (begin -> info) != '(' ) {
begin = OutStack(begin,&a); // Считываем элемент из стека
OutStr += a; // Записываем в строку
}
begin = OutStack(begin,&a); // Удаляем из стека скобку «(»
}
// Букву (операнд) заносим в выходную строку
if (ss >= 'a' && ss <= 'z' ) OutStr += ss;
/* Если знак операции, то переписываем из стека в выходную строку все опера-ции с большим или равным приоритетом */
if (znak.Contains(ss)) {
while ( begin != NULL && Prior (begin -> info) >= Prior (ss) ) {
begin = OutStack(begin, &a);
OutStr += a;
}
begin = InStack(begin, ss);
}
}
// Если стек не пуст, переписываем все операции в выходную строку
while ( begin != NULL){
begin = OutStack(begin, &a);
OutStr += a;
}
Edit2->Text = OutStr; // Выводим полученную строку
}
//---------------------- Текст функции-обработчика кнопки Посчитать ---------------
char ch;
String OutStr = Edit2->Text;
for (int i=1; i<Kol; i++) {
ch = StringGrid1->Cells[0][i][1];
mas[int(ch)]=StrToFloat(StringGrid1->Cells[1][i]);
}
Edit3->Text=FloatToStr(Rezult(OutStr));
//------------------ Функция реализации приоритета операций ---------------------------
int Prior ( char a ){
switch ( a ) {
case '^': return 4;
case '*': case '/': return 3;
case '-': case '+': return 2;
case '(': return 1;
}
return 0;
}
//-------------------- Расчет арифметического выражения ---------------------------------
double Rezult(String Str) {
char ch, ch1, ch2;
double op1, op2, rez;
znak << '*' << '/' << '+' << '-' << '^';
char chr = 'z'+1;
for (int i=1; i <= Str.Length(); i++){
ch=Str[i];
if (! znak.Contains(ch)) begin = InStack(begin, ch);
else {
begin = OutStack(begin,&ch1);
begin = OutStack(begin,&ch2);
op1 = mas[int (ch1)];
op2 = mas[int (ch2)];
switch (ch){
case '+' : rez=op2+op1; break;
case '-' : rez=op2-op1; break;
case '*' : rez=op2*op1; break;
case '/' : rez=op2/op1; break;
case '^' : rez=pow(op2,op1); break;
}
mas[int (chr)] = rez;
begin = InStack(begin,chr);
chr++;
}
}
return rez;
}
Рис. 4.1