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

2 回复

我有两点意见。

  1. 为什么 cas(matrixA, matrixB, nbColumn1, nbLine2) 是并发运行的?它不必也不应该是,因为你在下面几行使用了切片,而该切片可能(并且几乎100%不会)包含你想要的数据。
  2. cas 函数中,你试图从切片中获取数据。看看它在调试器中的样子。 Screenshot 2020-11-25 at 16.30.39

索引为 2 的元素不存在,因为索引是 0 和 1。

更多关于Golang中使用goroutines实现矩阵乘积的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的代码存在几个关键问题导致索引越界错误。主要问题在于:

  1. 结果矩阵未初始化result 切片在使用前没有分配内存
  2. goroutine参数传递错误:传递给cas函数的参数不正确
  3. 循环边界硬编码:使用了固定的循环边界而不是矩阵的实际维度

以下是修正后的代码:

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()
    }
}

主要修正点:

  1. 使用sync.WaitGroup等待所有goroutine完成
  2. 正确初始化结果矩阵:result := make([][]int, rows1)并分配每行的内存
  3. 使用正确的循环边界:for i := 0; i < rows1; i++而不是硬编码的i <= 2
  4. 将矩阵作为参数传递给goroutine函数,避免使用全局变量
  5. 每个goroutine计算结果矩阵的一个元素,使用正确的行列索引
回到顶部