На этом шаге мы приведем общие сведения о массивах.
Архитектура большинства компьютеров по технологическим причинам строится так, что программные переменные располагают в линейном (одномерном) порядке. Это имеет далеко идущие последствия, касающиеся распространённых программистских привычек. В частности, если в процессе программирования понадобилось большое количество переменных для объектов одного и того же типа, то рекомендуется использовать структуру данных "массив".
Одномерные массивы (или векторы) образуют важный специальный класс массивов.
Приведем несколько демонстрационных примеров.
-- Функция увеличивает каждый элемент числовой матрицы на 1 ----------------------------------------------------------- addElt:: [[Int]] -> [[Int]] addElt lst = map (addEl) lst --------------------------------------------------------- -- Функция увеличивает на 1 каждый элемент одноуровневого -- числового списка ---------------------- addEl:: [Int] -> [Int] addEl lst = map (1+) lst ------------------------------ -- Неудачные тестовые примеры: ---------------------------------------------- test = addElt [[(-9),2,-23,67],[23,3,7,675], [34,2,4,7],[23,-7,6,8]] == [[-8,3,-22,68],[24,4,8,676],[35,3,5,8],[24,-6,7,9]] && addElt [[(-92)],[233],[342],[-76]] == [[-91],[234],[343],[-75]]
-- Функция вычисляет сумму значений элементов: -- (1) в n-ой строке; -- (2) в n-ом столбце числовой матрицы. -- Нумерация начинается с 0 ------------------------------ sumStr:: Int -> [[Int]] -> Int sumStr n lst | null lst = 0 | n==0 = sum (head lst) | True = sumStr (n-1) (tail lst) ------------------------------------------------- sumKol:: Int -> [[Int]] -> Int sumKol n lst | null lst || n>(length (head lst))-1 = 0 | True = ((head lst)!!n)+sumKol n (tail lst) --------------------------------------------------------- -- Неудачные тестовые примеры: ------------------------------------------------------- test = sumStr 1 [[1,2,2],[23,2,21],[234,33,34]] == 46 && sumStr 3 [[1,2,2],[23,2,21],[234,33,34],[0,9,7]] == 16 --------------------------------------------------------------- test1 = sumKol 2 [[1,2,12,90,89]] == 12 && sumKol 3 [[1,2,12,90,89],[23,45,(-2),9,1], [23,2,1,-9,-4]] == 90 && sumKol 4 [[1,2,12,90,89],[23,45,(-2),9,1], [23,2,1,-9,-4]] == 86 -----------------------------------------
-- Функция определяет количество ненулевых элементов: -- (1) в n-ой строке заданной матрицы; -- (2) в n-ом столбце числовой матрицы. -- Нумерация начинается с 0 --------------------------------- notnulStr:: Int -> [[Int]] -> Int notnulStr n lst | null lst || (n>(length (head lst)-1)) = 0 | n==0 = nenul 0 (head lst) | True = notnulStr (n-1) (tail lst) ---------------------------------------------------- -- Функция возвращает количество ненулевых элементов -- в числовом одноуровневом списке (при обращении к -- функции накапливающий параметр n=0) -------------------------------------- nenul:: Int -> [Int] -> Int nenul n lst | null lst = n | (head lst)/=0 = nenul (n+1) (tail lst) | True = nenul n (tail lst) ------------------------------------------------ notnulKol:: Int -> [[Int]] -> Int notnulKol n lst | null lst || n>length (head lst) - 1 = 0 | (head lst) !! n/=0 = 1 + notnulKol n (tail lst) | True = notnulKol n (tail lst) -- ********************************************* -- Неудачные тестовые примеры: --------------------------------------------------------------- test = notnulStr 0 [[2],[3]] == 1 && notnulStr 0 [[23,34,-3,0,4]] == 4 && notnulStr 1 [[23,34,-3,0,4,8,9],[23,4,5,4,4,3,0]] == 6 && notnulStr 2 [[23,34,-3,0,4,8,9],[23,4,5,4,4,3,0], [7,8,7,7,0,789,6]] == 6 --------------------------------------------------------------- test1 = notnulKol 1 [[3,0,56],[5,6,7],[6,7,8]] == 2 && notnulKol 2 [[3,0,56],[5,6,7],[6,7,8]] == 3 && notnulKol 0 [[3,0,56],[0,6,7],[6,7,8]] == 2 && notnulKol 1 [[3,0,56]] == 0
-- Функция вычисляет суммы значений элементов числовой матрицы, -- расположенных в первой и последней строке матрицы, а также - -- в её первом и последнем столбце ---------------------------------- sumElem:: [[Int]] -> Int -> Int sumElem lst i | null lst = 0 | i==0 = sum (head lst)+sumElem (tail lst) 1 | null (tail lst) = sum (head lst) | True = head (head lst)+last (head lst)+ sumElem (tail lst) i -- ******************************************** -- Неудачные тестовые примеры: ------------------------------ test = sumElem [[9,0]] 0 == 9 && sumElem [[9,0,12,8,9],[0,8,9,2,-6]] 0 == 51 && sumElem [[9,0,12,8,9],[0,8,9,2,-6],[8,5,6,4,3]] 0 == 58 && sumElem [[9,1],[3,2]] 0 == 15 && sumElem [[9,1],[3,2],[23,4]] 0 == 42 && sumElem [[9,1,3],[3,2,4],[2,23,4]] 0 == 49
-- Функция вычисляет произведение значений элементов -- числовой матрицы, расположенных на её диагоналях; -- при вызове функции i=0 ---------------------------------- multy_diag:: [[Int]] -> Int -> Int multy_diag lst i | null lst && i==0 = 0 | null lst || i>=n = 1 | i/=n-(i+1) = (head lst !! i) * (head lst !! (n-(i+1))) * multy_diag (tail lst) (i+1) | True = (head lst !! i) * multy_diag (tail lst) (i+1) where n = length (head lst) -- *************************** -- Неудачные тестовые примеры: ----------------------------------------------------- test = multy_diag [[2,3,3],[3,1,1],[3,5,2]] 0 == 36 && multy_diag [[2,3],[3,4]] 0 == 72 && multy_diag [[2,3,3],[3,4,4],[1,1,1]] 0 == 24 -----------------------------------------------------
-- Функция, обнуляющую значение элементов (нумерация начинается -- с 0): -- (1) в n-ой строке матрицы; -- (2) в n-ом столбце матрицы; -- (3) на диагонали матрицы, начиная с элемента, находящегося -- на пересечении первой строки и первого столбца матрицы -- (на главной диагонали) ---------------------------------- nulStr:: Int -> [[Int]] -> [[Int]] nulStr n lst | null lst = [] | n==0 = [replicate m 0]++(tail lst) | True = [head lst]++nulStr (n-1) (tail lst) where m = length (head lst) ---------------------------------- nulKol:: Int -> [[Int]] -> [[Int]] nulKol n lst | null lst = [] | n>m-1 || n<0 = lst | True = [(take n (head lst))++[0]++(drop (n+1) (head lst))]++ nulKol n (tail lst) where m = length (head lst) ----------------------------------------------------- -- При обращении к функции накапливающий параметр i=0 ----------------------------------------------------- nulDiag:: Int -> [[Int]] -> [[Int]] nulDiag n lst | null lst = [] | n>((length (head lst))-1) = lst | True = [take n (head lst)++[0]++drop (n+1) (head lst)]++ nulDiag (n+1) (tail lst) -- ********************************* -- Неудачные тестовые примеры: -------------------------------------------------------------- test1 = nulStr 2 [[3,4],[5,6],[78,9]] == [[3,4],[5,6],[0,0]] && nulStr 0 [[2],[3],[4]] == [[0],[3],[4]] && nulStr 1 [[2],[3],[4],[90]] == [[2],[0],[4],[90]] ------------------------------------------------------------- test2 = nulKol 1 [[2,3,4],[4,5,4],[4,3,2]] == [[2,0,4],[4,0,4],[4,0,2]] && nulKol 2 [[2,3,4],[4,5,4],[4,3,2]] == [[2,3,0],[4,5,0],[4,3,0]] ------------------------------------------------------ test3 = nulDiag 0 [[2],[3],[4]] == [[0],[3],[4]] && nulDiag 0 [[2,3,4],[4,5,6]] == [[0,3,4],[4,0,6]] && nulDiag 0 [[2,3,4,5]] == [[0,3,4,5]] && nulDiag 0 [[23,4,5,6],[4,5,6,7],[45,6,7,7]] == [[0,4,5,6],[4,0,6,7],[45,6,0,7]] && nulDiag 0 [[1,2,3],[4,5,6],[3,4,5]] == [[0,2,3],[4,0,6],[3,4,0]] && nulDiag 0 [[123,45,6],[5,6,7],[7,89,90],[7,89,6],[6,7,88]] == [[0,45,6],[5,0,7],[7,89,0],[7,89,6],[6,7,88]]
-- Функция, меняющая местами n-ю и m-ю строки --------------------------------------------- swapStr:: [[Int]] -> Int -> Int -> [[Int]] swapStr lst i j | null lst || i==j || lst !! i==lst !! j = lst | i<j = take i lst ++ [lst!!j] ++ take (j-i-1) (drop (i+1) lst) ++ [lst !! i] ++ drop (j+1) lst | True = swapStr lst j i -- ***************************** -- Неудачные тестовые примеры: --------------------------------------------------------- test = swapStr [[3,4,6,8],[23,1,2,3],[4,5,6,7],[8,7,6,5]] 2 3 == [[3,4,6,8],[23,1,2,3],[8,7,6,5],[4,5,6,7]]
На следующем шаге мы приведем перечень задач для самостоятельного решения.