如何在压缩稀疏行(CRS)中按索引查找元素?Java代码排障
问题分析与修复方案
你的代码存在几处核心错误,导致get_element()始终返回0,以下是具体问题和修复后的代码:
核心问题
CRS格式的LI数组初始化错误
标准CRS的LI数组需以0开头,依次累加每行的非零元素数量,最后一个元素是总非零元素数。你的代码直接从第一行的非零数开始记录,导致后续索引计算完全偏移;且最后错误添加main.N+1,而非总非零元素数。列索引不匹配
构造函数中LJ.add(j+1)将列索引转为1-based,但get_element()中用户输入的是矩阵原始的0-based索引,导致无法匹配目标元素。print_all方法遍历范围错误
循环仅打印前main.N个元素,而非全部非零元素,无法完整验证CRS存储是否正确。get_element索引范围错误
因LI数组格式错误,导致定位目标行非零元素的范围完全错误,无法遍历到正确的元素位置。
修复后的代码
CRS类修复版
import java.util.Scanner; import java.util.ArrayList; public class CRS { private ArrayList<Integer> A = new ArrayList<>(); private ArrayList<Integer> LJ = new ArrayList<>(); private ArrayList<Integer> LI = new ArrayList<>(); public CRS(int[][] matrix) { int nonZeroCount = 0; LI.add(0); // 标准CRS起始指针为0 int rows = matrix.length; int cols = matrix[0].length; for(int i = 0; i < rows; i++) { for(int j = 0; j < cols; j++) { if(matrix[i][j] != 0) { A.add(matrix[i][j]); LJ.add(j); // 存储0-based列索引,与输入保持一致 nonZeroCount++; } } LI.add(nonZeroCount); // 记录当前累计的非零元素总数 } } public void print_all() { System.out.println("\nCRS Representation"); System.out.print("A (non-zero values): "); for(int val : A) { System.out.print(val + " "); } System.out.print("\nLJ (column indices): "); for(int col : LJ) { System.out.print(col + " "); } System.out.print("\nLI (row pointers): "); for(int ptr : LI) { System.out.print(ptr + " "); } System.out.println(); } public int get_element() { System.out.println("\n\nSearching for an element"); Scanner sc = new Scanner(System.in); System.out.println("Enter row index (0-based):"); int row = sc.nextInt(); System.out.println("Enter column index (0-based):"); int col = sc.nextInt(); int result = 0; // 检查行索引合法性 if(row < 0 || row >= LI.size() - 1) { System.out.println("Invalid row index"); sc.close(); return result; } int startIdx = LI.get(row); int endIdx = LI.get(row + 1); // 遍历目标行的非零元素 for(int k = startIdx; k < endIdx; k++) { if(LJ.get(k) == col) { result = A.get(k); break; // 找到元素后直接退出循环 } } sc.close(); return result; } }
Main类修复版(类名规范调整)
import java.util.*; public class Main { public static int N = 2; public static void main(String[] args) { int matrixSize = 10 * N; int[][] matrix = new int[matrixSize][matrixSize]; // 生成N个随机非零元素 for(int count = 0; count < N;) { int i = (int)(Math.random() * matrixSize); int j = (int)(Math.random() * matrixSize); if(matrix[i][j] == 0) { matrix[i][j] = 1 + (int)(Math.random() * 12); count++; } } // 打印原始稀疏矩阵 System.out.println("Sparse Matrix"); for(int i = 0; i < matrixSize; i++) { for(int j = 0; j < matrixSize; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); } CRS crs = new CRS(matrix); crs.print_all(); System.out.println("Result: " + crs.get_element()); } }
修复说明
- LI数组修正:以
0开头,每行处理完后记录累计非零元素数,保证目标行的元素索引范围正确。 - 列索引统一:LJ存储0-based列索引,与用户输入的矩阵索引一致,避免转换错误。
- 合法性检查:添加行索引合法性判断,避免数组越界异常。
- 效率优化:找到目标元素后立即退出循环,减少不必要的遍历。
- 资源回收:关闭Scanner避免资源泄漏。
- 代码规范:调整类名
main为Main,符合Java命名规范;使用增强for循环简化打印逻辑。
内容的提问来源于stack exchange,提问作者SaintSammy
相关产品推荐
相关产品推荐

