Loop diagonally through two dimensional array

前端 未结 12 1315
刺人心
刺人心 2020-12-05 11:52

I wrote the following code to walk half the diagonals of an array:

String[][] b = [a,b,c]
               [d,e,f]
               [g,h,i];  

public void LoopD         


        
相关标签:
12条回答
  • 2020-12-05 11:52

    Type 1: We can solve this using python very easily

    Code:

    r,c=map(int,input().split())
    mat=[[str(ch) for ch in input().split()]for _ in range(r)]
    for i in range(r*c-2):
        lis=[]
        for j in range(r):
            for k in range(c):
                if k+j==i:
                    lis.append(mat[j][k])
        print(*lis[::-1])
    

    Output:

    5 5
    a b c d e
    f g h i j
    k l m n o
    p q r s t
    u v w x y
    
    a
    f b
    k g c
    p l h d
    u q m i e
    v r n j
    w s o
    x t
    y
    
    0 讨论(0)
  • 2020-12-05 11:53

    I wrote the following code. The key is to exhaust all of the diagonals that start at the top and then move onto the diagonals that start on the sides. I included a method that combines the two angles to traverse diagonals Northwest - Southeast and Northeast - Southwest and stand alone methods for traversing the respective angles.

    public static void main(String[] args){
        int[][] m = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
        printDiagonals(m, DiagonalDirection.NEtoSW, new DiagonalVisitor() {     
            public void visit(int x, int y, int[][] m) {
                System.out.println(m[x][y]);
            }
        });
    }
    
    public enum DiagonalDirection{
        NWToSE,
        NEtoSW
    }
    
    private static abstract class DiagonalVisitor{
        public abstract void visit(int x, int y, int[][] m);
    }
    
    public static void printDiagonals(int[][] m, DiagonalDirection d, DiagonalVisitor visitor){
    
        int xStart = d==DiagonalDirection.NEtoSW ? 0 : m.length-1;
        int yStart = 1;
    
    
        while(true){
            int xLoop, yLoop;
            if(xStart>=0 && xStart<m.length){
                xLoop = xStart;
                yLoop = 0;
                xStart++;
            }else if(yStart<m[0].length){
                xLoop = d==DiagonalDirection.NEtoSW ? m.length-1 : 0;
                yLoop = yStart;
                yStart++;
            }else
                break;
    
            for(;(xLoop<m.length && xLoop>=0)&&yLoop<m[0].length; xLoop=d==DiagonalDirection.NEtoSW ? xLoop-1 : xLoop+1, yLoop++){
                visitor.visit(xLoop, yLoop, m);
            }
    
        }
    
    }
    
    public static void printDiagonalsNEtoSW(int[][] m, DiagonalVisitor visitor){
    
        int xStart = 0;
        int yStart = 1;
    
    
        while(true){
            int xLoop, yLoop;
            if(xStart<m.length){
                xLoop = xStart;
                yLoop = 0;
                xStart++;
            }else if(yStart<m[0].length){
                xLoop = m.length-1;
                yLoop = yStart;
                yStart++;
            }else
                break;
    
            for(;xLoop>=0 && yLoop<m[0].length; xLoop--, yLoop++){
                visitor.visit(xLoop, yLoop, m);
            }
    
    
        }
    }
    
    public static void printDiagonalsNWtoSE(int[][] m, DiagonalVisitor visitor){
    
        int xStart = m.length-1;
        int yStart = 1;
    
    
        while(true){
            int xLoop, yLoop;
            if(xStart>=0){
                xLoop = xStart;
                yLoop = 0;
                xStart--;
            }else if(yStart<m[0].length){
                xLoop = 0;
                yLoop = yStart;
                yStart++;
            }else
                break;
    
            for(;xLoop<m.length && yLoop<m[0].length; xLoop++, yLoop++){
                visitor.visit(xLoop, yLoop, m);
            }       
        }
    }
    
    0 讨论(0)
  • 2020-12-05 11:54

    Here is the code:

    public void loopDiag(String [][] b) {
    
            boolean isPrinted  = false;
            for (int i = 0 ; i < b.length ; i++) {
                String temp="";
                int x=i;
                for(int j = 0 ; j < b.length ; j++) {
                    int y = j;
                    while (x >= 0 && y < b.length) {
                        isPrinted = false;
                        temp+=b[x--][y++];                  
                    }
                    if(!isPrinted) {
                        System.out.println(temp);
                        isPrinted = true;
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-05 11:55

    Initialize array only for test purpose:

        int dim = 5;
        char ch = 'A';
        String[][] array = new String[dim][];
        for( int i = 0 ; i < dim ; i++ ) {
            array[i] = new String[dim];
            for( int j = 0 ; j < dim ; j++, ch++ ) {
                array[i][j] = "" + ch;
            }
        }
    

    Output our matrix:

        for( int i = 0 ; i < dim ; i++ ) {
            for( int j = 0 ; j < dim ; j++, ch++ ) {
                System.out.print( array[i][j] + " " );
            }
            System.out.println();
        }
        System.out.println( "============================" );
    

    Solution

    Element indexes from diagonals have one rule - their sum is constant on one diagonal:

    VARIANT 1

    Use two loops to extract all diagonals.

    First loop extracts top half of diagonals:

        for( int k = 0 ; k < dim ; k++ ) {
            for( int j = 0 ; j <= k ; j++ ) {
                int i = k - j;
                System.out.print( array[i][j] + " " );
            }
            System.out.println();
        }
    

    Second loop iterates on bottom half of diagonals:

        for( int k = dim - 2 ; k >= 0 ; k-- ) {
            for( int j = 0 ; j <= k ; j++ ) {
                int i = k - j;
                System.out.print( array[dim - j - 1][dim - i - 1] + " " );
            }
            System.out.println();
        }
    

    VARIANT 2

    Use one loop to extract all diagonals, but there are extra iterations and one additional check:

        for( int k = 0 ; k < dim * 2 ; k++ ) {
            for( int j = 0 ; j <= k ; j++ ) {
                int i = k - j;
                if( i < dim && j < dim ) {
                    System.out.print( array[i][j] + " " );
                }
            }
            System.out.println();
        }
    

    The output:

    A B C D E 
    F G H I J 
    K L M N O 
    P Q R S T 
    U V W X Y 
    ============================
    A 
    F B 
    K G C 
    P L H D 
    U Q M I E 
    V R N J 
    W S O 
    X T 
    Y 
    

    Update

    There are questions about rectangular matrix (height != width) in comments. Here is solution for rectangular matrix:

    The rule remains the same: Sum of element indexes from the same diagonal is constant

    The minimum sum of indexes is 0 (for first element in matrix with indexes [0;0])

    The maximum sum of indexes is width + height - 2 (for last element in matrix with indexes [height-1; with-1])

    Initialize rectangular matrix only for test purpose:

        int WIDTH = 7;
        int HEIGHT = 3;
        char ch = 'A';
        String[][] array = new String[HEIGHT][];
        for( int i = 0 ; i < HEIGHT ; i++ ) {
            array[i] = new String[WIDTH];
            for( int j = 0 ; j < WIDTH ; j++, ch++ ) {
                array[i][j] = "" + ch;
            }
        }
    

    Print our rectangular matrix:

        for( int i = 0 ; i < HEIGHT ; i++ ) {
            for( int j = 0 ; j < WIDTH ; j++, ch++ ) {
                System.out.print( array[i][j] + " " );
            }
            System.out.println();
        }
        System.out.println( "============================" );
    

    Solution

        for( int k = 0 ; k <= WIDTH + HEIGHT - 2; k++ ) {
            for( int j = 0 ; j <= k ; j++ ) {
                int i = k - j;
                if( i < HEIGHT && j < WIDTH ) {
                    System.out.print( array[i][j] + " " );
                }
            }
            System.out.println();
        }
    

    Output:

    A B C D E F G 
    H I J K L M N 
    O P Q R S T U 
    ============================
    A 
    H B 
    O I C 
    P J D 
    Q K E 
    R L F 
    S M G 
    T N 
    U 
    
    0 讨论(0)
  • 2020-12-05 11:58

    This is the same as what leoflower posted here. I've just changed the variable names for better understanding.

    level = denotes the current level of the diagonal that is being printed. Ex:- level = 2 denotes diagonal elements with indices (0,2),(1,1),(2,0)

    currDiagRowIndex = denotes row index of the current diagonal being printed

    currDiagColIndex = denotes columnn index of the current diagonal being printed

    void printMatrixDiagonal(int matrix[][], int endRowIndex, int endColIndex){
        for(int level = 0; level < endColIndex; level++){
            for(int currDiagRowIndex = 0, currDiagColIndex = level; currDiagRowIndex < endRowIndex && currDiagColIndex >= 0 ; currDiagRowIndex++, currDiagColIndex--){
                System.out.print(matrix[currDiagRowIndex][currDiagColIndex] + "  ");
            }
            System.out.println();
        }
    
        for(int level = 1; level < endRowIndex; level++){
            for(int currDiagRowIndex = level, currDiagColIndex = endColIndex-1; currDiagRowIndex < endRowIndex && currDiagColIndex >= 0; currDiagRowIndex++, currDiagColIndex--){
                System.out.print(matrix[currDiagRowIndex][currDiagColIndex]+ "  ");
            }
            System.out.println();
        }
    }
    

    Input:

    1 2 3 4 5 
    6 7 8 9 10
    11 12 13 14 15
    16 17 18 19 20
    21 22 23 24 25
    

    Output:

    1  
    2  6  
    3  7  11  
    4  8  12  16  
    5  9  13  17  21  
    10  14  18  22  
    15  19  23  
    20  24  
    25  
    
    0 讨论(0)
  • 2020-12-05 11:59

    This is how:

    int [][]mat = { {1,2,3},
                    {4,5,6},
                    {7,8,9},
    };
    
    int N=3;
    
    for (int s=0; s<N; s++) {
        for (int i=s; i>-1; i--) {
            System.out.print(mat[i][s-i] + " ");
        }
        System.out.println();
    }
    
    for (int s=1; s<N; s++) {
        for (int i=N-1; i>=s; i--) {
            System.out.print(mat[i][s+N-1-i] + " ");
        }
        System.out.println();
    }
    

    The first loop prints the diagonals beginning from first column, the second loop prints the remaining diagonals (beginning from bottom row).

    Output:

    1 
    4 2 
    7 5 3 
    8 6 
    9 
    
    0 讨论(0)
提交回复
热议问题