МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
федеральное государственное автономное образовательное учреждение высшего образования
«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»
(ГУАП)
КАФЕДРА № 44
Преподаватель
канд. техн. наук, доцент Бариков Л. Н.
Отчёт
по лабораторной работе №9
по дисциплине ОСНОВЫ ПРОГРАММИРОВАНИЯ
на тему: «Динамические массивы»
Работу выполнил
студент гр. Z9411 Кафка Р. С.
Санкт-Петербург
2020
Лабораторная работа №9
Динамические массивы
Цель лабораторной работы: изучение структурной организации динамических массивов и способов доступа к их элементам с использованием указателей; совершенствование навыков процедурного программирования на языке C/C++ при решении задач обработки динамических массивов.
Задание на программирование: используя технологию процедурного программирования, разработать программу обработки одномерных и двумерных (матриц) динамических массивов в соответствии с индивидуальным заданием.
Порядок выполнения работы:
1. Получить у преподавателя индивидуальное задание и выполнить постановку для каждой из задач: сформулировать условие, определить входные и выходные данные, их ограничения.
2. Разработать математические модели для каждой из задач: описать с помощью формул и рисунков структуру массивов и процесс их преобразования.
3. Построить схемы алгоритмов решения задач и основных функций.
4. Составить программу на языке C/C++.
5. Входные данные на этапах тестирования и демонстрации работы преподавателю должны задаваться либо с использованием специально подобранных арифметических формул, либо вводиться с клавиатуры по запросу. Датчики псевдослучайных чисел использовать запрещается.
Если это не оговорено в конкретном варианте задания, значения элементов в каждом исходном массиве должны быть разными.
6. Выходные данные должны выводиться на экран с пояснениями. Операторы вывода результатов работы должны находиться либо в функции main(), либо в специальной функции вывода (например, преобразованного массива), вызов которой осуществляется из функции main().
7. Проверить и продемонстрировать преподавателю работу программы на полном наборе тестов, в том числе с ошибочными входными данными. Входные и выходные массивы должны выводиться в одном и том же формате.
8. Использовать стандартные потоковые объекты ввода/вывода cin и cout.
9. Оформить отчет о лабораторной работе в составе: постановка задачи, математическая модель, схема алгоритма решения, текст программы, контрольные примеры (скриншоты).
Вариант №4. (студ. билет 2019/3603)
Формулировка задания:
А. Дан массив a0, a1, a2, …, an-1. Определить абсолютную величину произведения значений элементов массива с чётными номерами, лежащих между элементом с минимальным значением и первым элементом массива с отрицательным значением.
Б. В заданной квадратной матрице размера 2n*2n найти среднее арифметическое значений отрицательных элементов области 6 (см. рисунок).
Решение задачи вариант A:
А. Дан массив a0, a1, a2, …, an-1. Определить абсолютную величину произведения значений элементов массива с чётными номерами, лежащих между элементом с минимальным значением и первым элементом массива с отрицательным значением.
Математическая модель решения
Решение задачи начинается с ввода исходных данных. Прежде всего, необходимо ввести значение (n) размера массива.
После этого необходимо задать значения всех элементов массива. Доступ к элементам массива осуществляется по их индексу (номеру данного элемента массива). Поэтому перебираем все индексы элементов массива от 0 до n-1 (нумерация элементов массива начинается с 0) и задаём значения элементов с текущими номерами.
Пусть исходный массив имеет вид (n=10):
0 |
1 |
|
|
|
|
|
|
n-2 |
n-1 |
4 |
-3 |
7 |
2 |
-5 |
-6 |
3 |
-2 |
-7 |
5 |
Теперь можно приступать к решению задачи. Вначале определяем номер элемента с минимальным значением. Принимаем за минимум первый по счёту элемент. Используем цикл, в котором перебираем значения элементов массива с 1 до n-1. Если значение меньше первого, то фиксируем индекс этого элемента i_min = i. Для упрощения дальнейшего кода присваиваем значение переменной min с помощью ссылки на переменную (&min).
Далее находим номер первого отрицательного элемента i_neg. Так же перебирая индексы элементов массива с 1 до n-1. Проверяем по условию чтобы значение было отрицательным (< 0). Как только оно нашлось, мы фиксируем номер элемента в i_neg, присваиваем значение в переменную neg с помощью ссылки (&neg). Завершаем цикл командой break, чтобы цикл не продолжил искать последующие отрицательные элементы. В случае если в массиве не будет отрицательных элементов, программа остановится, выведя ошибку на экран. После чего программу можно будет ещё раз запустить или завершить.
Затем, для корректной работы программы, проверяем: не совпадают ли минимальный элемент массива с первым отрицательным элементом, т.к. при совпадении подсчитать абсолютную величину произведения будет не из чего (между одинаковыми элементами нет чисел). Если всё в порядке – программа продолжает работу, если нет – остановится, выведя ошибку на экран с дальнейшим перезапуском или завершением.
В конце подсчитываем абсолютную величину произведения значений элементов массива mult. В программе сначала присваиваем значению mult = 1, находить величину будем с помощью функции, в которой присвоим значение для переменной с помощью ссылки (&mult). Для этого запускаем цикл с шагом 2, т.к. нам нужны чётные номера. Значения в нём перебираем в зависимости того, какой элемент будет в массиве первый:
- Если первое отрицательное число стоит раньше минимального, то перебираем индексы от первого отрицательного значения i_neg до минимального значения i_min.
- Если минимальное число стоит раньше первого отрицательного, то перебираем индексы от минимального i_min до первого отрицательного значения i_neg. (Но, логически рассуждая, такого быть не может в данных условиях постановки задачи, т.к. либо в этом массиве не будет отрицательных чисел, либо оба элемента массива будут одинаковыми. Оба этих случая приведут к ошибке.)
Как только цикл закончится проверяем значение на наличие минуса, при необходимости отбрасываем его чтобы получилось абсолютное значение.
В результате абсолютная величина произведения значений элементов массива с чётными номерами, лежащих между элементом с минимальным значением и первым элементом массива с отрицательным значением зафиксирована в переменной mult. Выводим её на экран.
Для рассматриваемого примера otr=-3, min=-7, элементы с чётными номерами: 7, -5, 3. Абсолютная величина произведения значений элементов массива с чётными номерами mult=105
0 |
1 |
2 |
|
4 |
|
6 |
|
m-2 |
m-1 |
4 |
-3 |
7 |
2 |
-5 |
-6 |
3 |
-2 |
-7 |
5 |
|
iotr |
|
|
|
|
|
|
imin |
|
Задача решена.
Схема алгоритма подсчета абсолютной величины произведения значений элементов массива (функция absoluteValueMult)
Схема алгоритма поиска номера минимального значения(функция minValue) и поиска номера первого отрицательного значения(функция firstNegative)
Текст программы (вариант А)
/*Массивы динамические одномерные
Определить абсолютную величину произведения значений элементов
массива с чётными номерами, лежащих между элементом с минимальным
значением и первым элементом массива с отрицательным значением.*/
#include <iostream>
#include <locale.h>
using namespace std;
typedef int telem; //объявление типа элемента массива
typedef telem* tmas; //объявление типа "указатель на telem"
void fillArray(tmas arr, int n);
void showArray(tmas arr, int n);
int minValue(tmas arr, telem &min, int n);
int firstNegative(tmas arr, telem &neg, int n);
void areEqual(int i, int j);
void absoluteValueMult(tmas arr, telem &mult, int i_min, int i_neg);
int main()
{
int n; //размер массива
int i; //для выбора повторить/завершить программу
setlocale(LC_ALL, "Russian");
cout << "\n Определить абсолютную величину произведения значений элементов";
cout << "\n массива с чётными номерами, лежащих между элементом с минимальным";
cout << "\n значением и первым элементом массива с отрицательным значением.";
//Ввод исходных данных
cout << "\n Введите количество элементов массива: ";
cin >> n;
tmas arr = new telem[n]; /*создание переменной-указателя на telem,
выделение динамической памяти под массив
адрес начала области заносится в arr*/
int i_min; //номер элемента с минимальным значением
int i_neg; //номер первого элемента с отрицательным значением
telem min; //значение минимального элемента
telem neg; //значение первого отрицательного элемента
telem mult = 1; //значение абсолютного произведения
fillArray(arr, n);
showArray(arr, n);
i_min = minValue(arr, min, n); //Поиск номера элемента с минимальным значением
i_neg = firstNegative(arr, neg, n); //Поиск номера первого элемента с отрицательным значением
cout << " Элемент с минимальным значением: " << min << ", под номером: " << i_min << endl;
cout << " Первый элемент массива с отрицательным значением: " << neg << ", под номером: " << i_neg << endl;
areEqual(i_min, i_neg); //Проверка: между элементами должен быть интервал
absoluteValueMult(arr, mult, i_min, i_neg);
cout << "\n Абсолютная величина произведения значений элементов массива ";
cout << "\n с чётными номерами, лежащие между элементом с минимальным значением ";
cout << "\n и первым элементом массива с отрицательным значением: " << mult << endl;
delete[] arr; //освобождение динамической памяти
cout << "\n Повторить-1, Выход-2: ";
cin >> i;
if (i == 1) main();
return 0;
}
void absoluteValueMult(tmas arr, telem &mult, int i_min, int i_neg)
{
int start, stop;
if (i_neg < i_min) { //Если первое отрицательное число стоит раньше минимального
stop = i_min;
if (i_neg % 2 == 0) //проверка на чётность
start = i_neg + 2; //чётное - начать со следующего чётного
else start = i_neg + 1;
}
else { //Если минимальное число стоит раньше первого отрицательного
stop = i_neg;
if (i_min % 2 == 0)
start = i_min + 2;
else start = i_min + 1;
}
cout << "\n Элементы с чётными номерами: ";
for (int i = start; i < stop; i += 2) {
cout << *(arr + i) << " ";
mult *= *(arr + i);
}
if (mult < 0) mult *= -1;
}
int minValue(tmas arr, telem &min, int n)
{
int i_min = 0; //За минимум принимаем первый по счёту элемент
min = arr[0];
for (int i = 1; i < n; i++) {
if (min > *(arr + i)) {
min = *(arr + i);
i_min = i;
}
}
return i_min;
}
int firstNegative(tmas arr, telem& neg, int n)
{
int i;
int i_neg;
for (int i = 0; i < n; i++) {
if (*(arr + i) < 0) {
neg = *(arr + i);
i_neg = i;
return i_neg;
}
}
cout << " В данном массиве нет отрицательных элементов. Выполнение программы невозможно. ";
cout << "\n Повторить-1, Выход-2: ";
cin >> i;
if (i == 1) main();
exit(1);
}
void fillArray(tmas arr, int n)
{
cout << " Введите одной строкой элементы массива из ";
cout << n << " чисел и нажмите <Enter>" << endl << " ";
for (int i = 0; i < n; i++) {
cin >> *(arr + i);
}
}
void showArray(tmas arr, int n)
{
cout << " Массив имеет вид: " << endl;
for (int i = 0; i < n; i++)
{
cout << *(arr + i) << " ";
}
cout << endl;
}
void areEqual(int i, int j) {
int k;
if (i == j) {
cout << " В данном массиве оба элемента совпадают по номеру и значению. Выполнение программы невозможно. ";
cout << "\n Повторить-1, Выход-2: ";
cin >> k;
if (k == 1) main();
exit(1);
}
}
Скриншот результатов выполнения программы (вариант А)