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

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

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

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

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

Текст 2 страницы из документа "48466"

Далее функция CircuarShift, осуществляющая циклический сдвиг строк матрицы вверх, или вниз. Направление сдвига определяется булевым параметром shiftUp, передаваемым процедуре:

  1. {

  2. осуществляет циклический сдвиг строк матрицы arr вверх при shiftUp = true,

  1. и вниз, при shiftUp = false

  2. }

  3. procedure CircuarShift(var arr: TMatrix; shiftUp: boolean);

  4. var

  5. RowN: integer;

  6. tmpRow: TVector;//временная переменная для хранения строки иатрицы

  7. begin

  8. if high(arr) < 1 then exit;//если в матрице меньше двух строк - выходим

  9. if shiftUp then

  10. begin//если сдвиг вверх

  11. tmpRow:= arr[high(arr)];//сохраним последнюю строку матрицы

  12. arr[high(arr)]:= arr[0];//приравняем последнюю строку первой

  13. for rowN:= 0 to high(arr)-2 do

  14. begin//для строк с нулевой по пред-предпоследнюю

  15. arr[rowN]:= arr[rowN+1];//текущая строка равна нижней

  16. end;

  17. arr[high(arr)-1]:= tmpRow;//предпоследнюю строку приравняем последней

  18. end

  19. else

  20. begin//иначе, если сдвиг вниз

  21. tmpRow:= arr[0];//сохраним нулвую строку

  22. arr[0]:= arr[high(arr)];//приравняем нулевую строку последней

  23. for rowN:= high(arr) downto 2 do

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

  25. arr[RowN]:= arr[RowN-1];//текущая строка равна верхней

  26. end;

  27. arr[1]:= tmpRow;//первую строку приравняем нулевой

  28. end;

  29. end;

«Разворачивание» матрицы

Процедура UnwindMatrix осуществляет "разворачивание" матрицы в одномерный массив против часовой стрелки. Эта процедура в своих локальных переменных хранит координаты текущего элемента, текущее направление обхода (посредством перечислимого типа TDirection), а так же границы ещё не обойдённой части матрицы, которые сужаются каждый раз, когда проходится целая строка, или столбец. В этот же момент меняется направление обхода и текущим становится элемент в этом направлении. Обход завершается, когда число пройденных элементов станет равняться количеству элементов в матрице:

  1. //перечисление - направления

  2. type TDirection = (down, right, up, left);

  1. {обходит матрицу arr против часовой стрелки и наполняет элементами массив res}

  2. procedure UnwindMatrix(const arr: TMatrix; var res: TVector);

  3. var

  4. count, cur: integer;//число элементов в матрице и счётчик элементов

  5. RowN, ColN: integer;

  6. leftB, bottomB, rightB, topB: integer;//границы обхода - меняются при проходе полной строки или столбца

  7. direction: TDirection;//текущее направление обхода

  8. begin

  9. if (length(arr) = 0) or (length(arr[0]) = 0) then exit;//если в матрице нет элементов - выходим

  10. count:= length(arr) * length(arr[0]);//подсчитаем число элементов в матрице

  11. SetLength(res, count);//выделим память для хранения всех элементов матрицы

  12. //начальные условия обхода: текущий элемент [0,0], границы совпадают с граниуцами матриы, направление - вниз

  13. direction:= down;

  14. RowN:= 0;

  15. ColN:= 0;

  16. leftB:= 0;

  17. bottomB:= high(arr);

  18. rightB:= high(arr[0]);

  19. topB:= 0;

  20. for cur:= 0 to count-1 do

  21. begin//пока не пройдём count элементов

  22. res[cur]:= arr[RowN, ColN];//добавляем текущий элемент в массив

  23. //дальненйшие действия зависят от текущего направления обхода

  24. case direction of

  25. down://если вниз

  26. if RowN < bottomB then inc(RowN)//если не дошли до нижней границы - сдвигаемся вниз

  27. else

  28. begin//иначе - прошли левый столбец

  29. direction:= right;//сменим направление на "вправо"

  30. inc(leftB);//сдвинем левую границу к центру

  31. inc(ColN);//сдвинемся вправо

  32. end;

  33. right://если вправо

  34. if ColN < rightB then inc(ColN)//если не дошли до правой границы - сдвигаемся вправо

  35. else

  36. begin//иначе - прошли нижнюю строку

  37. direction:= up;//сменим направление на "вверх"

  38. dec(bottomB);//сдвинем нижнюю границу к центру

  39. dec(RowN);//сдвинемся вверх

  40. end;

  41. up://если вверх

  42. if RowN > topB then dec(RowN)//если не дошли до верхней границы - сдвигаемся вверх

  43. else

  44. begin//иначе - прошли правый столбец

  45. direction:= left;//сменим направление на "влево"

  46. dec(rightB);//сдвинем правую границу к центру

  47. dec(ColN);//сдвинемся влево

  48. end;

  49. left://если влево

  50. if ColN > leftB then dec(ColN)//если не дошли до левой границы - сдвигаемся влево

  51. else

  52. begin//иначе - прошли верхнюю строку

  53. direction:= down;//сменим направление на "вниз"

  54. inc(topB);//сдвинем верхнюю границу к центру

  55. inc(RowN);//сдвинемся вниз

  56. end;

  57. end;

  58. end;

  59. end;

Сортировка строк матрицы

Наконец упорядочивание строк матрицы по убыванию суммы элементов каждой строки. Вспомогательная функция getRowSum возвращает сумму элементов заданной строки:

  1. {возвращает сумму элементов RowN-ой строки матрицы arr}

  2. function getRowSum(const arr: TMatrix; RowN: integer): Int64;

  1. var ColN: integer;

  2. begin

  3. Result:= 0;

  4. if RowN > high(arr) then exit;//если в матрице нет RowN-ой строки - выходим

  5. for ColN:= 0 to high(arr[RowN]) do//суммируем элементы строки

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

  7. end;

Сама сортировка осуществляется посредством процедуры SortRows. Был выбран алгоритм прямой вставки, так как число строк в матрице не предполагается большим, а этот алгоритм эффективен на небольших наборах данных. В любом случае сортировка осуществляется быстро, так как при перемене мест строк не происходит копирование данных, но просто переставляются местами указатели. Листинг этой функции:

  1. {сортирует строки матрицы по убыванию сумм элементов каждой строки}

  2. procedure SortRows(var arr: TMatrix);

  1. var

  2. i, k: integer;//переменные для алгоритма сортировки

  3. tmpRow: TVector;//временная переменная для алгоритма сортировки

  4. begin

  5. //алгоритм сортировки методом прямой вставки

  6. for i:= 1 to high(arr) do

  7. begin//для строк с первой по последнюю

  8. k:= i;//начиная с текущей строки

  9. while (k > 0) and (getRowSum(arr, k) > getRowSum(arr, k-1)) do

  10. begin//пока не дошли до нулевой строки, и сумма строки над текущей строкой больше текущей суммы

  11. swap(arr[k-1], arr[k]);//поменяем текущую строку и строку над ней местами

  12. dec(k);//сдвинемся вверх

  13. end;

  14. end;

  15. end;

2.3.2 Модуль fileIO

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

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

  1. {

  1. записывает матрицу arr в текстовый файл outFile. Файл должен быть

  2. предварительно открыт

  3. }

  4. procedure Write2DArray(const arr: TMatrix; const outFile: TextFile);

  5. var

  6. rowN, colN: integer;

  7. begin

  8. for rowN:= low(arr) to high(arr) do

  9. begin

  10. for colN:= low(arr[rowN]) to high(arr[rowN]) do

  11. begin

  12. //ширина поля 12, так как -2147483648 - 11 символов

  13. Write(outFile, arr[rowN, colN]: 12);

  14. end;

  15. Writeln(outFile);

  16. end;

  17. end;

Процедура Read2DArray читает файл по строкам, разбирая каждую строку на подстрока пробелами с помощью процедуры ExtractStrings:

  1. { читает матрицу arr из текстового файла inFile. Файл должен быть

  1. предварительно открыт}

  2. procedure Read2DArray(var arr: TMatrix; const inFile: TextFile);

  3. var

  4. rowN, colN: integer;

  5. colCount: integer; //максимальное количество чисел в строке (число столбцов матрицы)

  6. lineStr: string; //текущая строка

  7. strNumbers: TStringList;//текущая строка, разделённая на подстроки пробелами

  8. begin

  9. rowN:= 0;

  10. colCount:= 0;

  11. strNumbers:= TStringList.Create;

  12. arr:= nil;

  13. while not Eof(inFile) do

  14. begin

  15. Readln(inFile, lineStr);

  16. strNumbers.Clear;

  17. ExtractStrings([' '], [], PChar(lineStr), strNumbers); //разделим пробелами на подстроки

  18. if colCount < strNumbers.Count then colCount:= strNumbers.Count;

  19. SetLength(arr, rowN+1, colCount);//выделим память под новую строку

  20. for colN:= 0 to strNumbers.Count-1 do //для каждого числа в строке

  21. arr[rowN, colN]:= StrToIntDef(strNumbers[colN], 0);

  22. Inc(rowN);

  23. end;

  24. strNumbers.Destroy;

  25. end;

2.3.3 Модуль form

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

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

Опишем важные процедуры формы. Процедура ReadMatrix осуществляет чтение исходных данных из таблицы на форме в двумерный массив. Перед началом чтения процедура устанавливает размер массива:

  1. {заполнить матрицу в соответствии с содержанием таблицы на форме}

  1. procedure TMainForm.ReadMatrix;

  2. var rowN, colN: integer;

  3. begin

  4. SetLength(workMatrix, G_Matrix.RowCount-1, G_Matrix.ColCount-1);

  5. for rowN:= 0 to G_Matrix.RowCount-2 do

  6. for colN:= 0 to G_Matrix.ColCount-2 do

  7. workMatrix[rowN, colN]:= StrToIntDef(G_Matrix.Cells[colN+1, rowN+1], 0);

  8. end;

Процедура writeMatrix осуществляет обратную операцию, она заполняет поля таблицы в соответствии с массивом. Кроме этого она меняет значения числа строк и столбцов в соответствии с размерами массива:

  1. {заполнить таблицу на форме в соответствии с содержанием матрицы}

  2. procedure TMainForm.writeMatrix;

  1. var rowN, colN: integer;

  2. begin

  3. G_Matrix.Cells[1, 1]:= '';//если матрица пуста

  4. E_RowsN.Text:= IntToStr(high(workMatrix) + 1);

  5. if(E_RowsN.Text <> '0') then

  6. E_ColsN.Text:= IntToStr(high(workMatrix[low(workMatrix)]) + 1)

  7. else E_ColsN.Text:= '0';

  8. B_SetDimmsClick(self);

  9. //заполним таблицу

  10. for rowN:= low(workMatrix) to high(workMatrix) do

  11. for colN:= low(workMatrix[rowN]) to high(workMatrix[rowN]) do

  12. G_Matrix.Cells[colN+1, rowN+1]:= IntToStr(workMatrix[rowN, colN]);

  13. end;

Процедура B_SetDimmsClick является обработчиком нажатия кнопки «задать размеры». Она проверяет, не стали ли размеры меньше единицы, меняет число строк и столбцов в таблицах формы, а так же проставляет номера строк и столбцов:

  1. {обраюотчик уствновки размеров матрицы}

  1. procedure TMainForm.B_SetDimmsClick(Sender: TObject);

  2. var

  3. i: integer;

  4. RowsN, ColsN: integer;

  5. begin

  6. //значения размеров не должны быть меньше 1

  7. RowsN:= StrToIntDef(E_RowsN.Text, 0);

  8. if RowsN < 1 then begin RowsN:= 1; E_RowsN.Text:= '1' end;

  9. ColsN:= StrToIntDef(E_ColsN.Text, 0);

  10. if ColsN < 1 then begin ColsN:= 1; E_ColsN.Text:= '1' end;

  11. //число строк и столбцов в таблице, учитывая колонку и строку с номерами

  12. G_Matrix.RowCount:= RowsN + 1;

  13. G_Matrix.ColCount:= ColsN + 1;

  14. //в этих таблицах отображаются одномерные массивы из первого задания

  15. G_Task1B.RowCount:= RowsN;

  16. G_Task1C.RowCount:= RowsN;

  17. //одномерный массив из четвёртого задания имеет длину, равную числу элементов исходной матрицы

  18. G_Task4.ColCount:= RowsN * ColsN;

  19. //расставим номера строк и столбцов

  20. for i:= 0 to RowsN do

  21. begin

  22. G_Matrix.Cells[0, i+1]:= IntToStr(i+1);

  23. G_Task1B.Cells[0, i]:= IntToStr(i+1);

  24. G_Task1C.Cells[0, i]:= IntToStr(i+1);

  25. end;

  26. for i:= 0 to ColsN do

  27. G_Matrix.Cells[i+1, 0]:= IntToStr(i+1);

  28. for i:= 0 to RowsN * ColsN do

  29. G_Task4.Cells[i, 0]:= IntToStr(i+1);

  30. G_Matrix.Refresh;

  31. end;

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

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