矩阵中最大子矩阵之和
一、题目描述
获取二维数组中的最大子二维数组
要求:
- 以指定格式的文本文件形式输入数组。
- 数组由一维变为二维
- 给出单元测试/代码覆盖率的最终覆盖率的报告,撰写博客。
二、实现思路
不多bb,直接暴力破解。
三、实现代码
package maxsubmatrix
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
// 暴力破解
func MaxSubmatrixSum(matrix [][]int) int {
// 行和列数
r := len(matrix)
c := len(matrix[0])
maxSubmatrix := 0
for i := 0; i < r; i++ {
for j := 0; j < c; j++ {
for k := i; k < r; k++ {
for l := j; l < c; l++ {
sumSubmatrix := 0
for m := i; m < k+1; m++ {
for n := j; n < l+1; n++ {
sumSubmatrix += matrix[m][n]
}
}
if sumSubmatrix > maxSubmatrix {
maxSubmatrix = sumSubmatrix
}
}
}
}
}
return maxSubmatrix
}
// 读取文件中的文本信息,构建二维数组
func ReadMatrix(fileName string) ([][]int, error) {
// matrix保存构建好的矩阵
var matrix []([]int)
f, err := os.Open(fileName)
if err != nil {
fmt.Println("failed to read file")
return matrix, err
}
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
row := 0
col := 0
// 读取行
if scanner.Scan() {
row, err = strconv.Atoi(scanner.Text())
if err != nil {
fmt.Println("file formate error!")
return matrix, err
}
}
// 读取列
if scanner.Scan() {
col, err = strconv.Atoi(scanner.Text())
if err != nil {
fmt.Println("file formate error!")
return matrix, err
}
}
// 读取矩阵内容,构建二维矩阵
for scanner.Scan() {
line := scanner.Text()
eles := strings.Split(line, " ")
var arr []int
for i := 0; i < len(eles); i++ {
ele, err := strconv.Atoi(eles[i])
if err != nil {
fmt.Println("file format error")
return matrix, err
}
arr = append(arr, ele)
}
matrix = append(matrix, arr)
}
// 如果读取的行和列与数据中的行与列不相等
if row != len(matrix) || col != len(matrix[0]) {
fmt.Println("File format error !")
return matrix, err
}
return matrix, err
}
四、测试
使用golang自带的单元测试工具即可,使用方法在我的前面博客有讲:Golang单元测试、最大子数组、效能分析。
1. 测试案例
对于这个最大子矩阵的题目,测试的案例有如下几个矩阵:
对于text1.txt:
3
3
1 5 2
5 4 9
6 2 3
text1.txt矩阵的最大子矩阵之和应该是37.
对于text2.txt:
3
3
1 2 3
3 4 5
2 4 5
text2.txt矩阵的最大子矩阵之和应该是29。
text3.txt如下:
4
4
1 6 -9 3
-4 9 3 6
3 -6 1 6
3 9 4 -5
text3.txt表示的矩阵的最大子矩阵之和是:30。
对于text4.txt,如下所示:
2
2
1 1
1 1
text4.txt最大子矩阵之和是:4。
2. 测试代码
测试代码如下:
package maxsubmatrix
import (
"os"
"testing"
)
func TestMatrix1(t *testing.T) {
matrix, err := ReadMatrix("text1.txt")
if err != nil {
t.Error("failed to read matrix from file")
os.Exit(-1)
}
max := MaxSubmatrixSum(matrix)
t.Log(max)
}
func TestMatrix2(t *testing.T) {
matrix, err := ReadMatrix("text2.txt")
if err != nil {
t.Error("failed to read matrix from file")
os.Exit(-1)
}
max := MaxSubmatrixSum(matrix)
t.Log(max)
}
func TestMatrix3(t *testing.T) {
matrix, err := ReadMatrix("text3.txt")
if err != nil {
t.Error("failed to read matrix from file")
os.Exit(-1)
}
max := MaxSubmatrixSum(matrix)
t.Log(max)
}
func TestMatrix4(t *testing.T) {
matrix, err := ReadMatrix("text4.txt")
if err != nil {
t.Error("failed to read matrix from file")
os.Exit(-1)
}
max := MaxSubmatrixSum(matrix)
t.Log(max)
}
3. 测试结果
然后输出命令,进行单元测试:
go test submatrix_test.go -v
可以在控制台看到测试结果:
根据结果,符合我们的预期。
五、Golang覆盖率测试
然后就是显示单元测试的覆盖率,对于这个题目来说,并没有分支很少,可以说就一个主分支,覆盖率没啥好测的。
对于覆盖率,golang也自带了工具可以测试。
直接输入命令,就可以测试覆盖率,并且还可以可视化出来.
输入下面命令,把覆盖率信息写入到一个cover.out文件中,
go test -coverprofile cover.out
在控制台中并且输出覆盖率信息:
由图可知,该代码覆盖率是79.2%。然后还可以以可视化的形式展示,在控制台输入下面代码:
go tool cover -html=cover.out -o cover.html
就会生成一个cover.html文件,打开该文件,如下图所示:
可以看到图中对每一行代码是否测试到都进行了分析,绿色表示覆盖了,红色表示没有覆盖。
六、参考资料
覆盖率:https://stackoverflow.com/questions/10516662/how-to-measure-test-coverage-in-go/27284510#27284510
posted on 2021-03-31 16:40 FreestyleCoding 阅读(224) 评论(5) 编辑 收藏 举报