48466 (Работа с двумерными числовыми массивами)

2016-07-30СтудИзба

Описание файла

Документ из архива "Работа с двумерными числовыми массивами", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "48466"

Текст из документа "48466"

Содержание

Введение

1. Теоретическая часть

1.1 Общее понятие о массивах

1.1.1 Определение и область применения

1.1.2 Специфические типы массивов

1.1.3 Реализация массивов

1.1.4 Достоинства массивов

1.1.5 Недостатки массивов

1.2 Массивы в Object Pascal

1.2.1 Статические массивы

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

1.2.3 Функции для работы с массивами

1.3 Использование массивов в рамках проекта

2. Практическая часть

2.1 Постановка задачи

2.2 Функциональная структура приложения

2.3 Описание модулей

2.3.1 Модуль MatrixOperations

2.3.2 Модуль fileIO

2.4 Модуль form

3. Эксплуатационная документация

3.1 Описание применения

3.2 Руководство оператора

Выводы

Приложения

Введение

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

Часто перед программистами встают задачи, связанные с обработкой стразу множества значений данных. В таких случаях крайне неудобно для хранения каждого значения заводить отдельную именованную переменную. Для такой ситуации синтаксис многих языков предусматривает создание массивов – множеств переменных, доступ к которым осуществляется посредством одного имени (имени массива) и одного или нескольких индексов.

Данная курсовая работа рассматривает методики использования многомерных массивов в среде Delphi. Она демонстрирует использование встроенных возможностей языка, а так же применение широко известных операций над массивами, таких как последовательный обход значений, сортировка, циклический сдвиг.

1. Теоретическая часть

1.1 Общее понятие о массивах

1.1.1 Определение и область применения

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

Без использования массивов не обойтись в таких областях программирования как работа с базами данных, компьютерная графика, визуализация результатов научных экспериментов, статистический анализ. Массивы являются входными и выходными параметрами процедур сортировки.

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

В языках программирования, допускающих объявления программистом собственных типов, как правило, существует возможность создания типа «массив». В определении такого типа может указываться размер, тип элемента, диапазон значений и типы индексов. В дальнейшем возможно определение переменных созданного типа. Все такие переменные-массивы имеют одну структуру. Некоторые языки поддерживают для переменных-массивов операции присваивания (когда одной операцией всем элементам массива присваиваются значения соответствующих элементов другого массива).

1.1.2 Специфические типы массивов

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

Гетерогенным называется массив, в разные элементы которого могут быть непосредственно записаны значения, относящиеся к различным типам данных. Массив, хранящий указатели на значения различных типов, не является гетерогенным, так как собственно хранящиеся в массиве данные относятся к единственному типу — типу «указатель». Гетерогенные массивы удобны как универсальная структура для хранения наборов данных произвольных типов. Отсутствие их поддержки в языке программирования приводит к необходимости реализации более сложных схем хранения данных. С другой стороны, реализация гетерогенности требует усложнения механизма поддержки массивов в трансляторе языка.

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

1.1.3 Реализация массивов

Стандартным способом реализации статических массивов с одним типом элементов является следующий:

Под массив выделяется непрерывный блок памяти объёмом

S*m1*m2*m3…mn,

где S — размер одного элемента, а m1…mn — размеры диапазонов индексов (то есть количество значений, которые может принимать соответствующий индекс).

При обращении к элементу массива A[i1, i2, i3, … in] адрес соответствующего элемента вычисляется как

B+S*(i1p*m1+i2p*m2+…+i(n-1)p*mn-1+inp),

где B — база (адрес начала блока памяти массива), ikp-значение k-го индекса, приведённое к целому с нулевым начальным смещением.

Таким образом, адрес элемента с заданным набором индексов вычисляется так, что время доступа ко всем элементам массива одинаково. Первый элемент массива, в зависимости от языка программирования, может иметь различный индекс. Различают три основных разновидности массивов: с отсчетом от нуля (zero-based), с отсчетом от единицы (one-based) и с отсчетом от специфического значения заданного программистом (n-based).

Отсчет индекса элемента массивов с нуля более характерен для низкоуровневых языков программирования, однако этот метод был популяризирован в языках более высокого уровня языком программирования С.

Более сложные типы массивов — динамические и гетерогенные — реализуются сложнее.

1.1.4 Достоинства массивов

  • Быстрый доступ к элементам, причём время доступа не зависит от длины массива

  • Элементы расположены в памяти непосредственно друг за другом, что облегчает копирование и перемещение всего массива целиком

  • Отсутствие необходимости в дополнительной памяти

1.1.5 Недостатки массивов

  • для статического массива — отсутствие динамики, невозможность удаления или добавления элемента без сдвига других

  • для динамического и/или гетерогенного массива — более низкое (по сравнению со статическим) быстродействие и дополнительные накладные расходы на поддержку динамических свойств и/или гетерогенности.

  • при работе с массивом в отсутствие дополнительных средств контроля — угроза выхода за границы массива и повреждения «чужих» данных

1.2 Массивы в Object Pascal

Ключевое слово Array используется для определения одномерных и многомерные массивов данных. В Object Pascal существует два типа массивов

1.2.1 Статические массивы

Создаются с заранее определёнными, неизменяемыми размерами. Могут быть одномерными, или многомерными – во втором случае представляя из себя массив массивов (массивов массивов и так далее).

Величина каждой размерности определяется двумя способами, которые могут свободно сочетаться при определении многомерного массива:

  • Тип Index, где Index – целый тип, обычно Byte или Word. Диапазон типа определяет диапазон размерности, например 0..255 для Byte

  • Ordinal..Ordinal. Таким образом, можно непосредственно задать диапазон размерности, например 12..44.

  • Например:

  1. var

  2. wordArray : Array[Word] of Integer; // размер равен High(Word)

  3. multiArray : Array[Byte, 1..5] of char; // двумерный массив

  4. rangeArray : Array[5..20] of string; // размер равен 16

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

У для динамических массивов память заранее не выделяется, создаётся только указатель. У таких массивов необходимо задавать размер перед использованием. Например

SetLength(dynArray, 5);

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

Отдельные подмассивы многомерного динамического массива могут иметь разные размеры, так как по сути они являются отдельными массивами.

Пример определения динамических массивов:

  1. var

  1. byteArray: Array of Byte; // одномерный массив

  2. multiArray: Array of Array of string; // двумерный массив

1.2.3 Функции для работы с массивами

Copy (Source : array; StartIndex, Count : Integer ) : array – создает копию части массива.

High (type or variable): Ordinal type - возвращает верхнюю границу диапазона значений массива.

Length (const SourceArray: array): Integer - возвращает число элементов в массиве.

Low (type or variable): Ordinal type - возвращает нижнюю границу диапазона значений массива

SetLength (var ArrayToChange: Array type; Dim1Length: Integer {;Dim2Length: Integer; ...}) - изменяет размер динамического массива. Для многомерных массивов может принимать более одного параметра длины.

Slice (SourceArray: array; Count: Integer): array - создает часть массива для передачи его как параметр в процедуру или функцию.

При использовании динамических массивов необходимо помнить, что вызовы SetLength выделяют для массива дополнительную память, которую необходимо освобождать после окончания работы с массивом. Для этого ему нужно присвоить специальное значение nil.

1.3 Использование массивов в рамках данного проекта

Работа со статическими массивами более проста и менее затратна в плане использования ресурсов компьютера, но так как в задании нигде не оговариваются конкретные размеры исходных матриц, то было принято решение построить программу ну основе использования динамических массивов.

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

2. Практическая часть

2.1 Постановка задачи

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

Граничные условия на вводимые данные таковы:

  • Размеры матрицы должны лежать в пределах [1; 2147483647]. Если введено число, выходящее из этого диапазона, либо значение, не являющееся целым числом, то размер устанавливается равным единице.

  • Элементы матрицы должны лежать в пределах [-2147483648; 2147483647]. Если какой-то из элементов лежит вне этого диапазона, либо введёно значение, не являющееся целым числом, то элемент устанавливается равным нулю.

  • В заданиях, связанных с подсчётом сумм элементов, результат может лежать в пределах [-9223372036854775808; 9223372036854775807]. Если сумма выходит за эти пределы, результат не определён.

2.2 Функциональная структура программы

Программа разделена на три модуля:

MatrixOperations – различные операции с матрицей

fileIO – сохранение матрицы в файл/ чтение матрицы из файла

form – форма приложения, процедуры обмена данными между массивами и элементами формы. Структура связей модулей такова:

2.3 Описание модулей

2.3.1 Модуль MatrixOperations

Это основной модуль программы, содержащий процедуры для выполнения матричных операций, предусмотренных заданием.

Определяет повсеместно используемые типы «матрица» и «вектор»:

  1. type

  1. TVector = array of integer;

  2. TMatrix = array of TVector;

Поиск максимальных элементов в матрице.

Процедура GetMaxVals, которая, перебирая все строки матрицы, находит в каждой максимальный элемент, записывает его значение в массив maxVal, а его номер столбца в массив maxValCol. Предварительно процедура выделяет необходимую намять для этих массивов. Листинг:

  1. 1 {

  1. формирует массив максимальных элементов maxVal и массив номеров столбцов,

  1. содержащих максимальные элементы maxValCol на основе матрицы arr

  2. }

  3. procedure GetMaxVals(var maxVal, maxValCol: TVector; const arr: TMatrix);

  4. var

  5. RowN, ColN, maxInRow: integer;

  6. begin

  7. //выделим необходимый для каждого массива объём памяти

  8. SetLength(maxVal, high(arr)+1);

  9. SetLength(maxValCol, high(arr)+1);

  10. for RowN:= low(arr) to high(arr) do

  11. begin//для каждой строки

  12. maxVal[RowN]:= low(integer);//по умолчанию максимальное значение -2147483648

  13. maxValCol[RowN]:= -1;//по умолчанию номер столбца с макс элементом -1

  14. for ColN:= low(arr[RowN]) to high(arr[RowN]) do

  15. begin//для каждого столбца

  16. if arr[RowN, ColN] > maxVal[RowN] then

  17. begin//если элемент больше макс значения, то

  18. maxVal[RowN]:= arr[RowN, ColN];//максимальное значение приравняем элементу

  19. maxValCol[RowN]:= ColN;//номер столбца приравняем текущему столбцу

  20. end;

  21. end;

  22. end;

  23. end;

Суммы элементов между диагоналями

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

Функции GetSumAbove и GetSumBelow проходят соответствующие половины строк матрицы, для каждой строки высчитывая диапазон столбцов, из которых нужно суммировать элементы:

  1. {возвращает сумму элементов выше пересечения диагоналей матрицы arr}

  1. function GetSumAbove (const arr: TMatrix): Int64;

  2. var

  3. RowN, ColN: integer;

  4. lastColumn: integer;//номер столбца, содержащего элемент дальней диагонали минус 1

  5. begin

  6. Result:= 0;

  7. for RowN:= 0 to (high(arr) div 2) do

  8. begin//с нулевой, по средюю строку

  9. lastColumn:= high(arr)-RowN-1;//определим номер столбца последнего элемента, подлежащего суммированию

  10. //если число столбцов меньше числа строк, то последний столбец может оказаться ближе

  11. if lastColumn > high(arr[RowN]) then lastColumn:= high(arr[RowN]);

  12. for ColN:= RowN+1 to lastColumn do //просуммируем элементы в высчитаных пределах

  13. Result:= Result + arr[RowN, ColN];

  14. end;

  15. end;

  16. {возвращает сумму элементов ниже пересечения диагоналей матрицы arr}

  17. function GetSumBelow(const arr: TMatrix): Int64;

  18. var

  19. RowN, ColN: integer;

  20. lastColumn: integer;//номер столбца, содержащего элемент дальней диагонали минус 1

  21. begin

  22. Result:= 0;

  23. for RowN:= (high(arr) div 2)+1 to high(arr) do

  24. begin//со средней по последнюю строку

  25. lastColumn:= RowN-1;//определим номер столбца последнего элемента, подлежащего суммированию

  26. //если число столбцов меньше числа строк, то последний столбец может оказаться ближе

  27. if lastColumn > high(arr[RowN]) then lastColumn:= high(arr[RowN]);

  28. for ColN:= high(arr)-RowN+1 to lastColumn do //просуммируем элементы в высчитаных пределах

  29. Result:= Result + arr[RowN, ColN];

  30. end;

  31. end;

Процедура SwapAboveBelow таким же образом, как функция GetSumAbove, определяет, какие элементы лежат выше пересечения диагоналей, но не суммирует их, а каждый меняет местами с элементом того же столбца, симметричным текущему относительно верхней и нижней границ матрицы. Для смены используется вспомогательная процедура swap для целых чисел, определённая в этом же модуле:

  1. {вспомогательная процедура: поменять местами два целых числа}

  1. procedure swap(var first, second: integer);

  2. var tmp: integer;

  3. begin

  4. tmp:= first;

  5. first:= second;

  6. second:= tmp;

  7. end;

  8. {поменять местами элементы выше и ниже пересечения диагоналей матрицы arr}

  9. procedure SwapAboveBelow (var arr: TMatrix);

  10. var

  11. RowN, ColN: integer;

  12. lastColumn: integer;//номер столбца, содержащего элемент дальней диагонали минус 1

  13. begin

  14. for RowN:= 0 to (high(arr) div 2) do

  15. begin//с нулевой, по средюю строку

  16. lastColumn:= high(arr)-RowN-1;//определим номер столбца последнего элемента, подлежащего суммированию

  17. //если число столбцов меньше числа строк, то последний столбец может оказаться ближе

  18. if lastColumn > high(arr[RowN]) then lastColumn:= high(arr[RowN]);

  19. for ColN:= RowN+1 to lastColumn do//для каждого элемента в высчитаных пределах

  20. //поменяем его местами с элементом того же столбца, отстаящем на то же число строк, но от нижней границы матрицы

  21. swap(arr[RowN, ColN], arr[high(arr) - RowN, ColN]);

  22. end;

  23. end;

Циклический сдвиг строк

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Нет! Мы не выполняем работы на заказ, однако Вы можете попросить что-то выложить в наших социальных сетях.
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
4144
Авторов
на СтудИзбе
667
Средний доход
с одного платного файла
Обучение Подробнее