Golang中使用goroutines实现矩阵乘积
Golang中使用goroutines实现矩阵乘积 大家好,我正在编写我的第一个Go项目,但我不理解代码中的错误。
输入第一个矩阵的行数:2 输入第一个矩阵的列数:2 输入第二个矩阵的行数:2 输入第二个矩阵的列数:2 输入第一个矩阵的元素: 1 2 3 4
输入第二个矩阵的元素: 1 2 3 4
panic: runtime error: index out of range [2] with length 2
goroutine 18 [running]: main.cas(0xc0000763f0, 0x2, 0x2, 0xc00008a090, 0x2, 0x2, 0x2, 0x2) C:/Users/sabti/Documents/ProjetGo/code1.go:16 +0x148 created by main.results C:/Users/sabti/Documents/ProjetGo/code1.go:58 +0x45d panic: runtime error: index out of range [2] with length 2
goroutine 20 [running]: main.cas(0xc0000763f0, 0x2, 0x2, 0xc00008a090, 0x2, 0x2, 0x2, 0x2) C:/Users/sabti/Documents/ProjetGo/code1.go:16 +0x148 created by main.results C:/Users/sabti/Documents/ProjetGo/code1.go:58 +0x45d panic: runtime error: index out of range [2] with length 2
goroutine 19 [running]: main.cas(0xc0000763f0, 0x2, 0x2, 0xc00008a090, 0x2, 0x2, 0x2, 0x2) C:/Users/sabti/Documents/ProjetGo/code1.go:16 +0x148 created by main.results C:/Users/sabti/Documents/ProjetGo/code1.go:58 +0x45d exit status 2
以下是我的代码:
package main
import (
"fmt"
)
var matrixA [][]int
var matrixB [][]int
var result [][]int
var numLigne, numColone int
var i, j, k, nbLine1, nbColumn1, nbLine2, nbColumn2, total, nbLigeR, nbColumnR int
func cas(matrix1 [][]int, matrix2 [][]int, numLine int, numColumn int) {
for i = 0; i < nbColumn1; i++ {
for j = 0; j < nbLine2; j++ {
total = total + matrix1[numLine][i]*matrix2[j][numColumn]
}
}
result[numLine][numColumn] = total
}
func results() {
fmt.Print("Enter the number of rows the first matrix: ")
fmt.Scanln(&nbLine1)
fmt.Print("Enter the number of columns the first matrix: ")
fmt.Scanln(&nbColumn1)
fmt.Print("Enter the number of rows the second matrix: ")
fmt.Scanln(&nbLine2)
fmt.Print("Enter the number of columns the second matrix : ")
fmt.Scanln(&nbColumn2)
if nbColumn1 != nbLine2 {
fmt.Println("Error: The matrix cannot be multiplied")
} else {
matrixA = make([][]int, nbLine1)
fmt.Println("Enter the first matrix elements: ")
for i = 0; i < nbLine1; i++ {
matrixA[i] = make([]int, nbColumn1)
for j = 0; j < nbColumn1; j++ {
fmt.Scanln(&matrixA[i][j])
}
}
matrixB = make([][]int, nbLine2)
fmt.Println("Enter the second matrix elements: ")
for i = 0; i < nbLine2; i++ {
matrixB[i] = make([]int, nbColumn2)
for j = 0; j < nbColumn2; j++ {
fmt.Scanln(&matrixB[i][j])
}
}
}
for i = 0; i <= 2; i++ {
for j = 0; j <= 2; j++ {
go cas(matrixA, matrixB, nbColumn1, nbLine2)
}
}
for i = 0; i < 2; i++ {
for j = 0; j < 2; j++ {
fmt.Print(result[i][j], "\t")
}
}
}
func main() {
results()
}
更多关于Golang中使用goroutines实现矩阵乘积的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我有两点意见。
- 为什么
cas(matrixA, matrixB, nbColumn1, nbLine2)是并发运行的?它不必也不应该是,因为你在下面几行使用了切片,而该切片可能(并且几乎100%不会)包含你想要的数据。 - 在
cas函数中,你试图从切片中获取数据。看看它在调试器中的样子。
索引为 2 的元素不存在,因为索引是 0 和 1。
更多关于Golang中使用goroutines实现矩阵乘积的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你的代码存在几个关键问题导致索引越界错误。主要问题在于:
- 结果矩阵未初始化:
result切片在使用前没有分配内存 - goroutine参数传递错误:传递给
cas函数的参数不正确 - 循环边界硬编码:使用了固定的循环边界而不是矩阵的实际维度
以下是修正后的代码:
package main
import (
"fmt"
"sync"
)
func multiplyElement(matrix1, matrix2 [][]int, row, col int, result [][]int, wg *sync.WaitGroup) {
defer wg.Done()
sum := 0
for k := 0; k < len(matrix1[0]); k++ {
sum += matrix1[row][k] * matrix2[k][col]
}
result[row][col] = sum
}
func main() {
var rows1, cols1, rows2, cols2 int
fmt.Print("Enter the number of rows for the first matrix: ")
fmt.Scanln(&rows1)
fmt.Print("Enter the number of columns for the first matrix: ")
fmt.Scanln(&cols1)
fmt.Print("Enter the number of rows for the second matrix: ")
fmt.Scanln(&rows2)
fmt.Print("Enter the number of columns for the second matrix: ")
fmt.Scanln(&cols2)
if cols1 != rows2 {
fmt.Println("Error: Matrices cannot be multiplied")
return
}
matrixA := make([][]int, rows1)
fmt.Println("Enter the first matrix elements:")
for i := 0; i < rows1; i++ {
matrixA[i] = make([]int, cols1)
for j := 0; j < cols1; j++ {
fmt.Scan(&matrixA[i][j])
}
}
matrixB := make([][]int, rows2)
fmt.Println("Enter the second matrix elements:")
for i := 0; i < rows2; i++ {
matrixB[i] = make([]int, cols2)
for j := 0; j < cols2; j++ {
fmt.Scan(&matrixB[i][j])
}
}
result := make([][]int, rows1)
for i := 0; i < rows1; i++ {
result[i] = make([]int, cols2)
}
var wg sync.WaitGroup
for i := 0; i < rows1; i++ {
for j := 0; j < cols2; j++ {
wg.Add(1)
go multiplyElement(matrixA, matrixB, i, j, result, &wg)
}
}
wg.Wait()
fmt.Println("Result matrix:")
for i := 0; i < rows1; i++ {
for j := 0; j < cols2; j++ {
fmt.Printf("%d\t", result[i][j])
}
fmt.Println()
}
}
主要修正点:
- 使用
sync.WaitGroup等待所有goroutine完成 - 正确初始化结果矩阵:
result := make([][]int, rows1)并分配每行的内存 - 使用正确的循环边界:
for i := 0; i < rows1; i++而不是硬编码的i <= 2 - 将矩阵作为参数传递给goroutine函数,避免使用全局变量
- 每个goroutine计算结果矩阵的一个元素,使用正确的行列索引

