左下三角矩阵压缩(Python)

目录

导语

解决方案

1. 以行为主的存储映射

2. 以列为主的存储映射

示例题目

1. 题目描述

2. 输入/输出 描述

3. 代码

4. 代码走读

5. 测试用例

A. 正常使用场景

B. 输入的数据不是整数

C. 输入的矩阵行数不大于0

6. 传送门


 

导语

下三角矩阵就是一种对角线以上元素都为0的 n x n矩阵。其中左下三角矩阵是指对角线以上的元素都为0。

由于下三角矩阵仍然有大量元素为0,为了避免浪费太多的内存空间,可以把三角矩阵的二维模式存储在一维列表中。

 

a_{11} 0 0 0 0
a_{21} a_{22} 0 0 0
a_{31} a_{32} a_{33} 0 0
... ... ... ... 0
a_{n1} a_{n2} a_{n3} ... a_{nn}

对于如上所示的 n x n左下三角矩阵A(ij),如果i < j,那么对应位置的元素值为0。

 

解决方案

由于采用Python解决这个问题,一维列表不需要实现声明大小。将该矩阵的有效元素映射为一维列表存储有两种解决方案,映射方式分为以行为主和以列为主两种方式。

1. 以行为主的存储映射

以行为主的存储方案是先将左下三角矩阵的第一行对角线及对角线以下的元素存储在一维列表中,然后在将左下三角矩阵的第二行对角线及对角线以下的元素存储在一维列表中。。。以此类推存储每一行元素。这样存储的一维列表中包含了左下三角矩阵中全部的有效元素。

a_{11} a_{21} a_{22} a_{31} a_{32} a_{33} ... a_{n1} a_{n2} a_{n3} ... a_{nn}

由上图可知a_{ij}在一维数组中所对应的索引值k的对应关系为:

k = n \cdot (j - 1) + i - \frac{j(j-1)}{2}

2. 以列为主的存储映射

同理,以列为主的存储如图:

a_{11}
a_{21}
a_{31}
...
a_{n1}
...
a_{ij}
...
...
a_{nn}

由上图可知a_{ij}在一维数组中所对应的索引值k的对应关系为:

k = n \cdot (j - 1) + i - \frac{j(j-1)}{2}


无论选择哪一种存储映射,都可以将左下三角矩阵压缩为一个一维列表。本文选用以列为主的存储映射举例说明

 

示例题目

1. 题目描述

设计一个Python程序,输入一个左下三角矩阵,输出压缩后的一维数组。

 

2. 输入/输出 描述

输入描述

输入左下三角矩阵的总行数、默认数字,然后自动计算大小,提示输入对应的数字。

Input matrix rows: 5
Input default value: 0
lower_triangular_matrix[0][0]: 34
lower_triangular_matrix[1][0]: 25
lower_triangular_matrix[1][1]: 39
lower_triangular_matrix[2][0]: 21
lower_triangular_matrix[2][1]: 23
lower_triangular_matrix[2][2]: 1
lower_triangular_matrix[3][0]: 98
lower_triangular_matrix[3][1]: 2
lower_triangular_matrix[3][2]: 56
lower_triangular_matrix[3][3]: 4
lower_triangular_matrix[4][0]: 59
lower_triangular_matrix[4][1]: 0
lower_triangular_matrix[4][2]: 2
lower_triangular_matrix[4][3]: 11
lower_triangular_matrix[4][4]: 3

输出描述:

输出原左下三角矩阵和压缩成一维列表后的矩阵。

------lower triangular matrix------
|	34	0	0	0	0	|
|	25	39	0	0	0	|
|	21	23	1	0	0	|
|	98	2	56	4	0	|
|	59	0	2	11	3	|
------compress lower triangular matrix --> list ------
[34, 25, 39, 21, 23, 1, 98, 2, 56, 4, 59, 0, 2, 11, 3]

 

3. 代码



class MatrixException(Exception):
    def __init__(self, message, code):
        self.message = message
        self.code = code


# 1. 输入一个左下三角矩阵
try:
    rows = int(input("Input matrix rows: "))
    if rows <= 0:
        raise MatrixException("Matrix rows can not less than zero.", 1002)
    columns = rows
    default_value = int(input("Input default value: "))

    ltm = [[default_value] * columns for row in range(rows)]
    for row in range(rows):
        for column in range(columns):
            if column <= row:
                ltm[row][column] = int(input("lower_triangular_matrix[%d][%d]: "
                                             % (row, column)))
except ValueError as e:
    print("errcode: %s" % str(1001))
    print("errmsg: %s" % str(e))
    exit(1001)
except MatrixException as e:
    print("errcode: %s" % e.code)
    print("errmsg: %s" % e.message)
    exit(e.code)

# 2. 压缩左下三角矩阵
try:
    array_size = ((1 + rows) * rows) // 2
    compress = [None] * array_size

    pos = 0
    for row in range(rows):
        for column in range(columns):
            if column <= row:
                compress[pos] = ltm[row][column]
                pos += 1

    if None in compress:
        print("compress: %s" % compress)
        raise MatrixException("Compress upper triangular matrix failed.", 1002)
except MatrixException as e:
    print("errcode: %s" % e.code)
    print("errmsg: %s" % e.message)
    exit(e.code)


# 3. 打印结果
print("------lower triangular matrix------")

for row in range(rows):
    message = "|\t"
    for column in range(columns):
        message += str(ltm[row][column]) + "\t"
    message += "|"
    print(message)

print("------compress lower triangular matrix --> list ------")
print(compress)

 

4. 代码走读

# 自定义异常
class MatrixException(Exception):
    def __init__(self, message, code):
        self.message = message
        self.code = code


# 1. 输入一个左下三角矩阵
try:
    # 输入左下三角矩阵的行数,列数等于行数
    rows = int(input("Input matrix rows: "))
    if rows <= 0:
        raise MatrixException("Matrix rows can not less than zero.", 1002)
    columns = rows
    # 输入默认数字
    default_value = int(input("Input default value: "))

    # 初始化左下三角矩阵
    ltm = [[default_value] * columns for row in range(rows)]
    for row in range(rows):
        for column in range(columns):
            if column <= row:
                ltm[row][column] = int(input("lower_triangular_matrix[%d][%d]: "
                                             % (row, column)))
except ValueError as e:
    print("errcode: %s" % str(1001))
    print("errmsg: %s" % str(e))
    exit(1001)
except MatrixException as e:
    print("errcode: %s" % e.code)
    print("errmsg: %s" % e.message)
    exit(e.code)

# 2. 压缩左下三角矩阵,使用以列为主的存储映射
try:
    array_size = ((1 + rows) * rows) // 2
    compress = [None] * array_size

    pos = 0
    for row in range(rows):
        for column in range(columns):
            if column <= row:
                compress[pos] = ltm[row][column]
                pos += 1

    if None in compress:
        print("compress: %s" % compress)
        raise MatrixException("Compress upper triangular matrix failed.", 1002)
except MatrixException as e:
    print("errcode: %s" % e.code)
    print("errmsg: %s" % e.message)
    exit(e.code)


# 3. 打印结果
print("------lower triangular matrix------")

for row in range(rows):
    message = "|\t"
    for column in range(columns):
        message += str(ltm[row][column]) + "\t"
    message += "|"
    print(message)

print("------compress lower triangular matrix --> list ------")
print(compress)

 

5. 测试用例

A. 正常使用场景

Input matrix rows: 6
Input default value: 0
lower_triangular_matrix[0][0]: 34
lower_triangular_matrix[1][0]: 12
lower_triangular_matrix[1][1]: 5
lower_triangular_matrix[2][0]: 9
lower_triangular_matrix[2][1]: -3
lower_triangular_matrix[2][2]: 23
lower_triangular_matrix[3][0]: 51
lower_triangular_matrix[3][1]: -24
lower_triangular_matrix[3][2]: 3
lower_triangular_matrix[3][3]: 1
lower_triangular_matrix[4][0]: 40
lower_triangular_matrix[4][1]: 22
lower_triangular_matrix[4][2]: 7
lower_triangular_matrix[4][3]: 92
lower_triangular_matrix[4][4]: 99
lower_triangular_matrix[5][0]: 76
lower_triangular_matrix[5][1]: 29
lower_triangular_matrix[5][2]: -26
lower_triangular_matrix[5][3]: -2
lower_triangular_matrix[5][4]: 3
lower_triangular_matrix[5][5]: 6
------lower triangular matrix------
|	34	0	0	0	0	0	|
|	12	5	0	0	0	0	|
|	9	-3	23	0	0	0	|
|	51	-24	3	1	0	0	|
|	40	22	7	92	99	0	|
|	76	29	-26	-2	3	6	|
------compress lower triangular matrix --> list ------
[34, 12, 5, 9, -3, 23, 51, -24, 3, 1, 40, 22, 7, 92, 99, 76, 29, -26, -2, 3, 6]

B. 输入的数据不是整数

Input matrix rows: k
errcode: 1001
errmsg: invalid literal for int() with base 10: 'k'

C. 输入的矩阵行数不大于0

Input matrix rows: 0
errcode: 1002
errmsg: Matrix rows can not less than zero.

 

6. 传送门

input()函数

int()函数

range()函数

print()函数

exit()函数

ValueError异常

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章