Добавил:
t.me Установите расширение 'SyncShare' для решения тестов в LMS (Moodle): https://syncshare.naloaty.me/ . На всякий лучше отключить блокировщик рекламы с ним. || Как пользоваться ChatGPT в России: https://habr.com/ru/articles/704600/ || Также можно с VPNом заходить в bing.com через Edge браузер и общаться с Microsoft Bing Chat, но в последнее время они форсят Copilot и он мне меньше нравится. || Студент-заочник ГУАП, группа Z9411. Ещё учусь на 5-ом курсе 'Прикладной информатики' (09.03.03). || Если мой материал вам помог - можете написать мне 'Спасибо', мне будет очень приятно :) Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторные работы / z9411_КафкаРС_лр_9_fixed3

.docx
Скачиваний:
17
Добавлен:
18.05.2022
Размер:
285.09 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

      1. федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

(ГУАП)

КАФЕДРА № 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);

}

}

Скриншот результатов выполнения программы (вариант А)

Решение задачи вариант Б:

Б. В заданной квадратной матрице размера 2n*2n найти среднее арифметическое значений отрицательных элементов области 6 (см. рисунок).

Математическая модель решения

Решение задачи начинается с ввода исходных данных. Из формулировки задачи понятно, что исходная матрица квадратная с чётным числом (2n) строк и столбцов. Следовательно, прежде всего, необходимо ввести значение (n) половины размера квадратной матрицы.

После этого необходимо задать значения всех элементов матрицы. Доступ к элементам двумерного массива (матрицы) осуществляется по двум индексам: номеру строки и номеру столбца, на пересечении которых находится данный элемент массива (нумерация строк и столбцов начинается с 0). Поэтому перебираем все строки (с 0-ой до 2n-1). Внутри каждой строки перебираем все столбцы (с 0-ого до 2n-1) и задаём значения элементов, лежащих на пересечении строки и столбца с текущими номерами.

Пусть в качестве примера исходная матрица имеет вид (n=5):

0

1

n-1

n

2n-2

2n-1

0

-0

-1

-2

-3

-4

-5

-6

-7

-8

-9

1

-10

-11

-12

-13

-14

-15

-16

-17

-18

-19

-20

-21

-22

-23

-24

-25

-26

-27

-28

-29

-30

-31

-32

-33

-34

-35

-36

-37

-38

-39

n-1

-40

-41

-42

-43

-44

-45

-46

-47

-48

-49

n

-50

-51

-52

-53

-54

-55

-56

-57

-58

-59

-60

-61

-62

-63

-64

-65

-66

-67

-68

-69

-70

-71

-72

-73

-74

-75

-76

-77

-78

-79

2n-2

-80

-81

-82

-83

-84

-85

-86

-87

-88

-89

2n-1

-90

-91

-92

-93

-94

-95

-96

-97

-98

-99

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

Поэтому в нахождении участвуют значения элементов строк с 0 до n-1 и элементы столбцов ниже побочной диагонали с n до 2n-2. Если значение элемента попадает в нужную область, то мы прибавляем его в общее значение суммы (sum) и увеличиваем счётчик элементов (count) на 1. Таким образом у нас получится общая сумма (sum), которую нужно поделить на количество (счётчик) этих элементов (count) и получится среднее значение (avg).

Задача решена.

Схема алгоритма нахождения среднего арифметическое значений отрицательных элементов области 6

Текст программы (вариант Б)

/*Массивы динамические двумерные.

В заданной квадратной матрице размера 2n*2n

найти среднее арифметическое значений

отрицательных элементов области 6 (см. рисунок).*/

#include<iostream>

#include<locale.h>

using namespace std;

typedef int telem; //определение типа элементов массива

typedef telem *tstr; //определение типа "указатель на telem"

typedef tstr *tmatr; //тип "указатель на указатель на telem"

void fillArray(tmatr, int);

void showArray(tmatr, int);

double calcArithmeticMean(tmatr arr, int n);

int main()

{

int n; //число строк (столбцов) матрицы

double avg;

tmatr arr; //переменная-указатель на указатель на telem

setlocale(LC_ALL, "Russian");

cout << " В заданной квадратной матрице размера 2n*2n \n";

cout << " найти среднее арифметическое значений \n";

cout << " отрицательных элементов области 6. \n";

cout << " Введите половину размера матрицы: n = ";

cin >> n;

arr = new tstr[2 * n]; /*выделение динамической памяти под массив

указателей на строки массива*/

for (int i = 0; i < 2 * n; i++) //выделение памяти под каждую строку:

*(arr + i) = new telem[2 * n]; /*каждому элементу массива указателей

на строки присваивается адрес начала

области памяти, выделяемой под строку*/

fillArray(arr, 2 * n);

cout << " Исходная матрица:\n";

showArray(arr, 2 * n);

avg = calcArithmeticMean(arr, n);

cout << " Среднее арифметическое значений отрицательных элементов:\n";

cout << avg << endl;

cout << endl << " Для завершения нажмите <Enter>";

//Освобождение динамической памяти

for (int i = 0; i < n; i++)

delete *(arr + i);

delete[]arr;

return 0;

}

void fillArray(tmatr arr, int n)

{

cout << " Значения элементов";

cout << " массива размера " << n << "x" << n;

cout << "\n при тестировании вводятся автоматически:" << endl;

for (int i = 0; i < n; i++)

for (int j = 0; j < n; j++)

*(*(arr + i) + j) = -(10 * i + j);

}

void showArray(tmatr arr, int n)

Соседние файлы в папке Лабораторные работы