You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strassen矩阵乘法算法报错求助:解决数组越界异常

Strassen矩阵乘法算法Java代码错误排查及修复

核心错误分析

抛出ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2的主要原因如下:

  • 结果矩阵初始化错误:mulMatx方法中,仅当矩阵阶数n=1时才正确初始化结果矩阵,当n>1时,C始终是1×1的矩阵。在后续合并子矩阵(joinMatx)时,尝试访问C[2][2]这类超出1×1范围的索引,直接触发越界异常。
  • 矩阵拆分逻辑颠倒:splitMatx方法的赋值逻辑完全反向,原本应该将主矩阵的子区域数据复制到子矩阵中,但代码写成了mainMat[i1][j1] = subMat[i2][j2],导致子矩阵始终是默认值0,且错误修改了原矩阵数据。
  • 矩阵合并参数顺序错误:joinMatx方法的参数传递顺序与内部逻辑不匹配,方法内部是将第一个参数的内容写入第二个参数,但实际调用时传入的是子矩阵在前、结果矩阵在后,导致无法正确合并结果。
  • 矩阵加减方法的数组初始化问题:addMatx和subMatx中创建结果矩阵时使用new int[A.length][B.length],虽然测试用例是方阵,但逻辑上应该保持行列数与输入矩阵一致,应改为new int[A.length][A.length](因Strassen算法仅适用于同阶方阵)。

修复后的完整代码

import java.util.*;

public class Main {

    public static int[][] mulMatx(int[][] A, int[][] B) {
        int n = A.length;
        // 初始化结果矩阵为n×n,而非固定1×1
        int[][] C = new int[n][n];
        
        if (n == 1) {
            C[0][0] = A[0][0] * B[0][0];
        } else {
            int half = n / 2;
            // 子矩阵初始化
            int[][] A11 = new int[half][half];
            int[][] A12 = new int[half][half];
            int[][] A21 = new int[half][half];
            int[][] A22 = new int[half][half];
        
            int[][] B11 = new int[half][half];
            int[][] B12 = new int[half][half];
            int[][] B21 = new int[half][half];
            int[][] B22 = new int[half][half];
        
            // 拆分主矩阵到子矩阵(修复后的逻辑)
            splitMatx(A, A11, 0, 0);
            splitMatx(A, A12, 0, half);
            splitMatx(A, A21, half, 0);
            splitMatx(A, A22, half, half);
        
            splitMatx(B, B11, 0, 0);
            splitMatx(B, B12, 0, half);
            splitMatx(B, B21, half, 0);
            splitMatx(B, B22, half, half);
            
            // Strassen的7个中间乘积计算
            int[][] M1 = mulMatx(addMatx(A11, A22), addMatx(B11, B22));
            int[][] M2 = mulMatx(addMatx(A21, A22), B11);
            int[][] M3 = mulMatx(A11, subMatx(B12, B22));
            int[][] M4 = mulMatx(A22, subMatx(B21, B11));
            int[][] M5 = mulMatx(addMatx(A11, A12), B22);
            int[][] M6 = mulMatx(subMatx(A21, A11), addMatx(B11, B12));
            int[][] M7 = mulMatx(subMatx(A12, A22), addMatx(B21, B22));

            // 计算结果矩阵的四个象限
            int[][] C11 = addMatx(subMatx(addMatx(M1, M4), M5), M7);
            int[][] C12 = addMatx(M3, M5);
            int[][] C21 = addMatx(M2, M4);
            int[][] C22 = addMatx(subMatx(addMatx(M1, M3), M2), M6);

            // 合并子矩阵到结果矩阵(修复参数顺序后的调用)
            joinMatx(C, C11, 0, 0);
            joinMatx(C, C12, 0, half);
            joinMatx(C, C21, half, 0);
            joinMatx(C, C22, half, half);
        }    
        return C;    
    }

    // 修复拆分逻辑:将主矩阵的子区域复制到子矩阵
    public static void splitMatx(int[][] mainMat, int[][] subMat, int startRow, int startCol){
        int subSize = subMat.length;
        for(int i = 0; i < subSize; i++){
            for(int j = 0; j < subSize; j++){
                subMat[i][j] = mainMat[startRow + i][startCol + j];
            }
        }
    }

    // 修复合并逻辑:将子矩阵复制到主矩阵的指定位置
    public static void joinMatx(int[][] mainMat, int[][] subMat, int startRow, int startCol){
        int subSize = subMat.length;
        for(int i = 0; i < subSize; i++){
            for(int j = 0; j < subSize; j++){
                mainMat[startRow + i][startCol + j] = subMat[i][j];
            }
        }
    }

    public static int[][] addMatx(int[][] A, int[][] B){
        int n = A.length;
        int[][] C = new int[n][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                C[i][j] = A[i][j] + B[i][j];
            }
        }
        return C;
    }

    public static int[][] subMatx(int[][] A, int[][] B){
        int n = A.length;
        int[][] C = new int[n][n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < n; j++) {
                C[i][j] = A[i][j] - B[i][j];
            }
        }
        return C;
    }

    public static void printMatx(int[][] Mat) {
        for(int[] row : Mat){
            System.out.println(Arrays.toString(row));
        }
    }

    public static void main(String[] args) {
        int[][] matA = {
            {2, 4, 5, 9},
            {2, 12, 7, 5},
            {15, 8, 2, 5},
            {14, 4, 2, 5}
        };
        int[][] matB = {
            {7, 4, 2, 24},
            {15, 7, 2, 6},
            {10, 12, 2, 4},
            {9, 2, 6, 3}
        };
        printMatx(mulMatx(matA, matB));
    }
}

关键修复点说明

  1. 结果矩阵初始化:将int[][] C = new int[1][1];改为int[][] C = new int[n][n];,确保结果矩阵的大小与输入矩阵一致。
  2. 拆分方法逻辑修正:splitMatx中把赋值方向反转,从主矩阵的startRow+i和startCol+j位置取值,赋值给子矩阵的i,j位置。
  3. 合并方法参数与逻辑匹配:调整joinMatx的参数顺序为(结果矩阵,子矩阵,起始行,起始列),并修正内部赋值逻辑,将子矩阵的数据写入结果矩阵的对应区域。
  4. 矩阵加减方法的数组初始化:统一使用n×n的大小创建结果矩阵,保持与输入方阵的一致性。

内容的提问来源于stack exchange,提问作者Krit Vardhan Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 10:14:54