上/下三角、對稱矩陣
December 12, 2021- 上三角矩陣是對角線以下的元素均為 0,也就是 Aᵢⱼ = 0,i > j,例如:
- 1 2 3 4 5
- 0 6 7 8 9
- 0 0 10 11 12
- 0 0 0 13 14
- 0 0 0 0 15
- 下三角矩陣是對角線以上的元素均為 0,也就是 Aᵢⱼ = 0,i < j,例如:
- 1 0 0 0 0
- 2 6 0 0 0
- 3 7 10 0 0
- 4 8 11 13 0
- 5 9 12 14 15
- 對稱矩陣是元素對稱於對角線,例如:
- 1 2 3 4 5
- 2 6 7 8 9
- 3 7 10 11 12
- 4 8 11 13 14
- 5 9 12 14 15
上三角或下三角矩陣大部份元素不儲存值(為 0),可以使用一維陣列來儲存以節省空間,對稱矩陣因為對稱於對角線,可以使用上三角或下三角矩陣來儲存。
解法思路
- 假設矩陣為 n x n,為了計算方便,讓陣列索引由 1 開始,上三角矩陣化為一維陣列,以列為主的公式為:
-
loc = n * (i - 1) - i * (i - 1)/ 2 + j
- 以行為主的公式為:
-
loc = j * (j - 1) / 2 + i
- 下三角矩陣化為一維陣列,以列為主的公式為:
-
loc = i * (i - 1) / 2 + j
- 以行為主的公式為:
-
loc = n * (j - 1) - j * (j - 1) / 2 + i
公式的導證是由等差級數公式得到,對於索引由 0 開始的語言來說,只要將 i 與 j 各加 1,求得 loc
後減 1,就可套用以上的公式。
程式實作
#include <stdio.h>
#include <stdlib.h>
#define N 5
int main(void) {
int arr1[N][N] = {
{1, 2, 3, 4, 5},
{0, 6, 7, 8, 9},
{0, 0, 10, 11, 12},
{0, 0, 0, 13, 14},
{0, 0, 0, 0, 15}};
int arr2[N*(1+N)/2] = {0};
int i, j, loc = 0;
printf("\n以列為主:");
for(i = 0; i < N; i++) {
for(j = 0; j < N; j++) {
if(arr1[i][j] != 0)
arr2[loc++] = arr1[i][j];
}
}
for(i = 0; i < N*(1+N)/2; i++)
printf("%d ", arr2[i]);
printf("\n輸入索引(i, j):");
scanf("%d, %d", &i, &j);
loc = N*i - i*(i+1)/2 + j;
printf("(%d, %d) = %d", i, j, arr2[loc]);
printf("\n");
return 0;
}
import java.util.*;
public class TriangleArray {
private List<Integer> list;
private int length;
public TriangleArray(int[][] array) {
length = array.length;
list = new ArrayList<Integer>(length * (1 + length) / 2);
for(int i = 0; i < length; i++) {
for(int j = 0; j < length; j++) {
if(array[i][j] != 0)
list.add(array[i][j]);
}
}
}
public int get(int i, int j) {
return list.get(length * i - i * (i + 1) / 2 + j);
}
public static void main(String[] args) {
int[][] array = {{1, 2, 3, 4, 5},
{0, 6, 7, 8, 9},
{0, 0, 10, 11, 12},
{0, 0, 0, 13, 14},
{0, 0, 0, 0, 15}};
TriangleArray triangleArray = new TriangleArray(array);
System.out.print(triangleArray.get(2, 2));
}
}
class TriangleArray:
def __init__(self, array):
self.__length = len(array)
self.__list = []
for i in range(self.__length):
for j in range(self.__length):
if array[i][j] != 0:
self.__list.append(array[i][j])
def get(self, i, j):
return self.__list[self.__length * i - i * (i + 1) // 2 + j]
array = [
[1, 2, 3, 4, 5],
[0, 6, 7, 8, 9],
[0, 0, 10, 11, 12],
[0, 0, 0, 13, 14],
[0, 0, 0, 0, 15]
]
triangleArray = TriangleArray(array)
print(triangleArray.get(2, 2))
class TriangleArray(array: Array[Array[Int]]) {
val length = array.length;
val arr = (for(i <- 0 until length; j <- 0 until length
if array(i)(j) != 0
) yield array(i)(j)).toArray
def get(i: Int, j: Int) = {
arr(length * i - i * (i + 1) / 2 + j)
}
}
val array = Array(
Array(1, 2, 3, 4, 5),
Array(0, 6, 7, 8, 9),
Array(0, 0, 10, 11, 12),
Array(0, 0, 0, 13, 14),
Array(0, 0, 0, 0, 15)
)
val triangleArray = new TriangleArray(array)
print(triangleArray.get(2, 2))
class TriangleArray
def initialize(array)
@length = array.length
@list = []
@length.times { |i|
@length.times { |j|
if array[i][j] != 0
@list << array[i][j]
end
}
}
end
def get(i, j)
@list[@length * i - i * (i + 1) / 2 + j]
end
end
array = [
[1, 2, 3, 4, 5],
[0, 6, 7, 8, 9],
[0, 0, 10, 11, 12],
[0, 0, 0, 13, 14],
[0, 0, 0, 0, 15]
]
triangleArray = TriangleArray.new(array)
puts triangleArray.get(2, 2)
class TriangleArray {
constructor(array) {
this.__length = array.length;
this.__list = [];
for(let i = 0; i < this.__length; i++) {
for(let j = 0; j < this.__length; j++) {
if(array[i][j] != 0) {
this.__list.push(array[i][j]);
}
}
}
}
elem(i, j) {
return this.__list[Math.floor(this.__length * i - i * (i + 1) / 2) + j];
}
}
let array = [
[1, 2, 3, 4, 5],
[0, 6, 7, 8, 9],
[0, 0, 10, 11, 12],
[0, 0, 0, 13, 14],
[0, 0, 0, 0, 15]
];
triangleArray = new TriangleArray(array);
console.log(triangleArray.elem(2, 2));
data TArray a = TArray Int [a]
triangleArray xs =
let row = length xs
in TArray row [xs !! i !! j | i <- [0..row - 1], j <- [0..(length $ xs !! 0) - 1], (xs !! i !! j) /= 0]
elemOf i j (TArray row xs) =
xs !! (row * i - (i * (i + 1)) `div` 2 + j)
main =
let
triArray = triangleArray [
[1, 2, 3, 4, 5],
[0, 6, 7, 8, 9],
[0, 0, 10, 11, 12],
[0, 0, 0, 13, 14],
[0, 0, 0, 0, 15]]
in
do
print $ elemOf 2 2 triArray