【问题标题】:Recursive function to check if a matrix is symmetric检查矩阵是否对称的递归函数
【发布时间】:2021-03-17 09:35:06
【问题描述】:

我有一个任务来实现矩阵类和一个检查矩阵是否对称的方法。 该方法必须是递归的,然后我必须计算它的复杂性。在我必须将递归函数转换为其迭代版本之后。

现在这是我的矩阵类的样子:

public class Matrix<T> {
    private int m, n;
    private T[][] data;

    public Matrix(int m, int n) {
        this.m = m;
        this.n = n;
    }

    public Matrix(T[][] data) {
        this.data = data;
    }

    public boolean isSymmetric() {
        if (m != n) {
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    if (data[i][j] != data[j][i]) {
                        return false;
                    }
                }
            }
            return true;
        }
        return false;
    }

    public boolean isSymmetric(int i, int j) {
        if (i < 0 && j < 0) return true;
        else {
            return isSymmetric(i - 1, j - 1);
        }
    }

    public T get(int i, int j) {
        return data[i][j];
    }

    public void set(int i, int j, T value) {
        data[i][j] = value;
    }

    public int[] getSize() {
        return new int[]{m, n};
    }

    @Override
    public String toString() {
        String rep = "";
        for (int i = 0; i < m; i++) {
            rep += "( ";
            for (int j = 0; j < n; j++) {
                rep += data[i][j].toString() + "\t";
            }
            rep += ")\n";
        }
        return rep;
    }
}

我有 isSymmetric() 函数的迭代版本,但我无法获得递归版本。

【问题讨论】:

    标签: java arrays recursion matrix symmetric


    【解决方案1】:

    在递归版本中,您忘记添加检查两个元素是否相等。没有它,该方法不会返回false。

    public boolean isSymmetric() {
        return m == n && isSymmetric(m - 1, n - 1);
    }
    
    public boolean isSymmetric(int i, int j) {
        if (i < 0 && j < 0) return true;
        else if (data[i][j] != data[j][i]) return false;
        else {
            return isSymmetric(i - 1, j - 1);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以从最大row 和col 开始检查,每次递归将减少1 直到0;

      public class Matrix<T> {
      
          private final int height;
          private final int width;
          private final T[][] data;
      
          public Matrix(T[][] data) {
              height = data.length;
              width = data[0].length;
              this.data = data;   // it brakes OOP: encapsulation
          }
      
          public boolean isSymmetricIterative() {
              if (height != width)
                  return false;
      
              for (int row = 0; row < height; row++)
                  for (int col = 0; col < width; col++)
                      if (data[row][col] != data[col][row])
                          return false;
      
              return true;
          }
      
          public boolean isSymmetricRecursive() {
              return isSymmetricRecursive(height - 1, width - 1);
          }
      
          private boolean isSymmetricRecursive(int row, int col) {
              return row < 0 && col < 0 || data[row][col] == data[col][row] && isSymmetricRecursive(row - 1, col - 1);
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        Symmetric matrix 是一个方阵,等于它的转置。假设我们有一个方阵。

        为避免不必要的迭代并降低时间复杂度,您可以只迭代矩阵左下角中的索引,并将相应的元素与那些元素进行比较在右上角m[i][j]==m[j][i],不包括主对角线,直到第一个不匹配。

        Try it online!

        // let's assume that we have a square matrix
        public static void main(String[] args) {
            int[][] matrix = {
                    {1, 2, 3, 4, 5},
                    {2, 3, 4, 5, 6},
                    {3, 4, 5, 6, 7},
                    {4, 5, 6, 7, 8},
                    {5, 6, 7, 8, 9}};
        
            System.out.println(isSymmetric(matrix)); // true
            System.out.println(isSymmetricR(matrix, 1, 0)); // true
        }
        
        // iterative version
        static boolean isSymmetric(int[][] matrix) {
            return IntStream.range(1, matrix.length)
                    .allMatch(i -> IntStream.range(0, i)
                            //intermediate output
                            .peek(j -> System.out.println("i=" + i + ",j=" + j))
                            .allMatch(j -> matrix[i][j] == matrix[j][i]));
        }
        
        // recursive version
        static boolean isSymmetricR(int[][] matrix, int i, int j) {
            if (i < matrix.length && j < i) {
                //intermediate output
                System.out.println("i=" + i + ",j=" + j);
                if (matrix[i][j] == matrix[j][i]) {
                    if (j == i - 1) {
                        return isSymmetricR(matrix, i + 1, 0);
                    } else {
                        return isSymmetricR(matrix, i, j + 1);
                    }
                } else {
                    // the first mismatch, the
                    // matrix is not symmetric
                    return false;
                }
            } else {
                // if reached this point,
                // the matrix is symmetric
                return true;
            }
        }
        

        两种情况的中间输出是一样的:

        i=1,j=0
        i=2,j=0
        i=2,j=1
        i=3,j=0
        i=3,j=1
        i=3,j=2
        i=4,j=0
        i=4,j=1
        i=4,j=2
        i=4,j=3
        

        另见:How to remove rows and columns containing only zeros from a 2d matrix?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-12
          • 1970-01-01
          • 1970-01-01
          • 2017-10-08
          • 2015-09-19
          • 2015-11-25
          • 2021-04-10
          • 2019-06-10
          相关资源
          最近更新 更多