Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 / 1

.docx
Скачиваний:
0
Добавлен:
16.05.2025
Размер:
220.64 Кб
Скачать

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

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

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

Кафедра вычислительных систем и сетей

ПРЕПОДАВАТЕЛЬ

Доцент, канд. техн. наук

Л.Н. Бариков

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

Лабораторная работа №1

Динамические массивы

по курсу: Основы программирования

СТУДЕНТКА ГР. №

Z0411

М.В.Карелина

номер группы

подпись, дата

инициалы, фамилия

Номер студенческого билета: 2020/3477

Санкт-Петербург

2022

Цель лабораторной работы:

Изучение структурной организации динамических массивов и способов доступа к их элементам с использованием указателей; совершенствование навыков процедурного программирования на языке C/C++ при решении задач обработки динамических массивов.

Порядок выполнения работы:

1. Получить у преподавателя индивидуальное задание и выполнить постановку для каждой из задач: сформулировать условие, определить входные и выходные данные, их ограничения.

2. Разработать математические модели для каждой из задач: описать с помощью формул и рисунков структуру массивов и процесс их преобразования.

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

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

5. Построить схемы алгоритмов решения задач и основных функций.

6. Составить программу на языке C/C++.

7. Входные данные на этапах тестирования и демонстрации работы преподавателю должны задаваться либо с использованием специально подобранных арифметических формул, либо вводиться с клавиатуры по запросу. Датчики псевдослучайных чисел использовать запрещается.

8. Выходные данные должны выводиться на экран с пояснениями. Операторы вывода результатов работы должны находиться либо в функции main(), либо в специальной функции вывода (например, преобразованного массива), вызов которой осуществляется из функции main().

9. Проверить и продемонстрировать преподавателю работу программы на полном наборе тестов, в том числе с ошибочными входными данными. Входные и выходные массивы должны выводиться в одном и том же формате.

10. Использовать стандартные потоковые объекты ввода/вывода cin и cout.

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

Вариант 28

А. Дан массив a0, a1, a2,…, a2n-1. Определить абсолютную величину суммы значений элементов массива с нечётными номерами, лежащих между последним элементом массива с положительным значением и элементом с номером n-1.

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

Решение задачи начинается с ввода исходных данных. Прежде всего, необходимо ввести значение (n) размера массива.

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

Пусть исходный массив имеет вид (n=10):

0

1

 

 

 

 

 

2n-1

1

8

-5

-3

5

7

6

-9

2

-11

Теперь можно приступать к решению задачи.

Вначале определяем элемента массива, имеющий индекс n-1, для простоты мы вводим переменную с и присваиваем ей значение n-1.

Далее определяем индекс последнего элемента массива с положительным значением. Для этого перебираем элементы массива с индексами от 0 до 2n-1. Если такой элемент в массиве есть, фиксируем факт его обнаружения в переменной flag и индекс этого элемента ipos и прекращаем перебор.

Если ни один элемент массива с положительным значением не найден, выполнение решения всей задачи прекращается.

Если в обоих случаях элементы массива найдены, то результат в нашем случае выглядит следующим образом:

0

1

 

 

 

 

 

2n-1

1

8

-5

-3

5

7

6

-9

2

-11

c

ipos

При этом логически возможно три случая: c<ipos, c>ipos и c=ipos.

В первом случае складываем значения элементов c нечетным индексом между c до ipos, а получившуюся сумму sum берем по модулю.

Во втором случае складываем значения элементов c нечетным индексом между ipos до с, а получившуюся сумму sum берем по модулю.

В третьем случае выполнение решения всей задачи прекращается.

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

Схема алгоритма поиска индекса последнего элемента массива с положительным значением (функция nomer_pos)

Схема алгоритма вычисления абсолютной величины суммы (функция abs_sum)

Код программы:

#include<iostream>

#include<stdlib.h>

#include<locale.h>

using namespace std;

const int RAZ = 20; //предельный размер массива

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

typedef telem tmas[RAZ];

int nomer_max(const tmas, int);

int nomer_pos(const tmas, int);

int abs_sum(const tmas, int, int);

void inputmas(tmas, int);

void outputmas(const tmas, int);

int main()

{

setlocale(LC_ALL, "Russian");

tmas a;

int n, imax, ipos, c;

telem sum;

cout << "\n Введите переменную n (Не больше 10) <= " << RAZ << " : ";

cin >> n;

c = n - 1;

n = n * 2 - 1;

//Контроль ввода размера массива

if (n > RAZ || n <= 0)

{

cout << "Введено недопустимое значение размера массива" << endl;

return 1;

}

inputmas(a, n);

cout << " Исходный массив:" << endl;

outputmas(a, n);

ipos = nomer_pos(a, n);

cout << "\n Индекс последнего элемента массива с положительным значением = " << ipos << endl;

cout << "\n Индекс элемента массива с номером n-1 = " << c << endl;

sum = abs_sum(a, c, ipos);

cout << "\n Абсолютная величина суммы: " << sum << endl;

return 0;

}

//Поиск индекса последнего элемента массива с положительным значением

int nomer_pos(const tmas a, int n)

{

int ipos,

flag = 0;

for (int i = n-1; i >= 0; i--)

if (a[i] > 0)

{

ipos = i;

flag = 1;

break;

}

if (flag == 1)

{

}

else {

cout << "\n Положительных элементов в массиве нет";

exit(3);

}

return ipos;

}

void inputmas(tmas a, int n)

{

cout << " Введите в одной строке элементы массива, состоящего из " << n;

cout << "\n чисел, и нажмите <Enter>" << endl;

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

cin >> a[i];

}

void outputmas(const tmas a, int n)

{

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

{

cout.width(4); //ширина поля для вывода значения элемента массива

cout << a[i] << " ";

}

}

telem abs_sum(const tmas a, int c, int ipos)

{

int i;

telem sum;

if (ipos != c)

{

sum = 0;

if (ipos < c)

{

for (i = ipos + 1; i < c; i++)

{

if (i % 2 == 0);

else

sum += a[i];

}

}

else

{

for (i = c + 1; i < ipos; i++)

{

if (i % 2 == 0);

else

sum += a[i];

}

}

}

else

{

cout << "\n Между ними нет элементов";

exit(3);

}

sum = fabs(sum);

return sum;

}

Скриншоты выполнения:

Б. В заданной квадратной матрице размера 2n*2n найти среднее арифметическое значений элементов области [4+5+6+7+8] (см. рисунок).

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

Решение задачи начинается с ввода исходных данных. Из формулировки задачи понятно, что исходная матрица квадратная с чётным числом (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

Теперь можно приступать к решению задачи. найти среднее арифметическое значений элементов области [4+5+6+7+8] (выделено зеленым).

Мы поочередно перебираем элементы в зеленой области и суммируем их значения в переменной summ. Так же каждый раз, когда мы это делаем мы увеличиваем счетчик num.

Для нахождения среднего арифметического, получившуюся сумму всех элементов области, делим на их количество, (summ/num), далее результат выводим через переменную sr_arif. Задача решена.

Схема алгоритма вычисления среднего арифметического значения (функция double_arif)

Код программы:

#include<iostream>

#include<locale>

#include <math.h>

using namespace std;

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

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

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

void check_size(int);

void input_matr(tmatr, int);

void output_matr(tmatr, int);

double arif(tmatr, int);

int main()

{

setlocale(LC_ALL, “Russian”);

tmatr a;

int n; // половина размера матрицы

cout << « Введите половину размера матрицы (не больше 5): n = «;

cin >> n;

check_size(n);

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

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

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

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

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

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

input_matr(a, n);

output_matr(a, n);

arif(a, n);

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

for (int I = 0; I < n; i++) //Освобождение динамической памяти

delete* (a + i);

delete[]a;

return 0;

}

void check_size(int n)

{

if (n <= 0)

{

cout << «\nТребуется ввод положительного значения половины размера матрицы!\n\n»;

main();

}

if (n > 5)

{

cout << «\nТребуется ввод значения половины размера матрицы не больше 5!\n\n»;

main();

}

}

void input_matr(tmatr a, int n)

{

cout << « Значения элементов массива размера « << n << «x» << n << « при тестировании вводятся автоматически:» << endl;

for (int I = 0; I < 2 * n; i++) //заполнения матрицы

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

*(*(a + i) + j) = 10 * I + j;

}

void output_matr(tmatr a, int n)

{

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

for (int I = 0; I < 2 * n; i++)

{

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

{

cout.width(3); //ширина поля выводимого параметра

cout << *(*(a + i) + j) << “ “;

}

cout << ‘\n’;

}

}

double arif(tmatr a, int n)

{

double sr_arif= 0.0;

double num = 0.0;

double summ = 0.0;

int k = 1;

for (int I = 0; I < 2 * n; i++)

{

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

{

um = um + a[i][j];

num++;

}

if (k < n)

{

k++;

}

else

{

k = 2 * n;

}

}

if (num == 0)

{

return -1;

}

sr_arif = um / num;

cout << “ \nСреднее среднее арифмитическое :” << sr_arif;

}

Скриншот выполнения:

Соседние файлы в папке 2