我写了下面的代码来走一半数组的对角线:
String[][] b = [a,b,c]
[d,e,f]
[g,h,i];
public void LoopDiag()
for (int i = b.length - 1; i > 0; i--) {
String temp = "";
for (int j = 0, x = i; x <= b.length - 1; j++, x++) {
temp = temp+b[x][j];
}
System.out.println(temp)
}
for (int i = 0; i <= b.length - 1; i++) {
String temp = "";
for (int j = 0, y = i; y <= b.length - 1; j++, y++) {
temp = temp+b[j][y];
}
System.out.println(temp);
}
}
现在它打印对角线,即电流输出:
g dh aei bf c
如何打印其他半对角线,即所需的输出:
a db gec hf i
答案 0 :(得分:15)
仅为测试目的初始化数组:
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;
}
}
输出我们的矩阵:
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( "============================" );
来自对角线的元素索引有一条规则 - 它们的和在一个对角线上是恒定的:
使用两个循环来提取所有对角线。
第一个循环提取对角线的上半部分:
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();
}
第二个循环遍历对角线的下半部分:
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();
}
使用一个循环来提取所有对角线,但有额外迭代和一次额外检查:
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();
}
输出:
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
评论中有关于矩形矩阵( height != width )的问题。这是矩形矩阵的解决方案:
规则保持不变:来自同一对角线的元素索引之和是恒定的
索引的最小总和为 0 (对于索引为[0; 0]的矩阵中的第一个元素)
索引的最大总和为 width + height - 2 (对于索引为[height-1; with-1]的矩阵中的最后一个元素)
仅为测试目的初始化矩形矩阵:
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;
}
}
打印矩形矩阵:
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( "============================" );
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();
}
输出:
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
答案 1 :(得分:4)
只是帮助自己,看看你需要循环的索引:
#1 (0,0) -> a
#2 (1,0) (0,1) -> bd
#3 (2,0) (1,1) (0,2) -> gec
#4 (2,1) (1,2) -> hf
#5 (2,2) -> i
查看每次迭代中索引的变化并创建算法。不那么困难,所以你自己做作业;)
答案 2 :(得分:4)
如果我们将其分解为2个子问题,解决方案会容易得多:
给定对角线的起始指数,打印对角线。
public void printMatrixDiagonals(int[][] matrix) {
int c = 0;
int count = matrix.length + matrix[0].length -1;
int i = 0, j = 0;
//There can be at most m + n -1 diagonals to be printed
while (c < count) {
//Start printing diagonals from i and j
printDiagonal(i, j, matrix);
if (i < matrix.length -1) {
//We increment row index until we reach the max number of rows
i++;
} else if (j < matrix[0].length - 1) {
//We are at maximum index of row; so its time to increment col index
//We increment column index until we reach the max number of columns
j++;
}
c++;
}
}
打印对角线:请注意,每次我们开始打印每个对角线时,行的索引应该递减,列的索引应该递增。因此,给定每个对角线的起始指数,我们可以按如下方式打印对角线:
private void printDiagonal(int i, int j, int[][] m) {
while (i >=0 && j< m[0].length ) {
System.out.print(m[i][j] + " ");
i--;
j++;
}
System.out.println("");
}
答案 3 :(得分:3)
我写了以下代码。关键是要排出从顶部开始的所有对角线,然后移动到从侧面开始的对角线。我提出了一种方法,它结合了两个角度来横穿对角线西北 - 东南和东北 - 西南,以及独立的方法来穿越各自的角度。
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);
}
}
}
答案 4 :(得分:2)
这适用于非方阵。理解起来很简单,但每对角线调用一次min()和max()。
int ndiags = width + height - 1;
System.out.println("---");
for (int diag = 0; diag < ndiags; diag++) {
int row_stop = Math.max(0, diag - width + 1);
int row_start = Math.min(diag, height - 1);
for (int row = row_start; row >= row_stop; row--) {
// on a given diagonal row + col = constant "diag"
// diag labels the diagonal number
int col = diag - row;
System.out.println(col + "," + row);
relax(col, row);
}
System.out.println("---");
}
此处输出的宽度= 3,高度= 3
---
0,0
---
0,1
1,0
---
0,2
1,1
2,0
---
1,2
2,1
---
2,2
---
width = 3,height = 2
---
0,0
---
0,1
1,0
---
1,1
2,0
---
2,1
---
width = 2,height = 3
---
0,0
---
0,1
1,0
---
0,2
1,1
---
1,2
---
答案 5 :(得分:1)
这是在while循环中打印对角矩阵的非常直观的方法。
将问题概括为整体而不是两部分,并根据空间复杂性进行优化。
package algorithm;
public class printDiagonaly
{
public static void main(String[] args)
{
int[][] a = new int[][]{{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20}};
int lr = 0;
int lc = -1;
int fr = -1;
int fc = 0;
int row = a.length - 1;
int col = a[0].length - 1;
while (lc < col || fc < col || fr < row || lr < row)
{
if (fr < row)
{
fr++;
}
else
{
fc++;
}
if (lc < col)
{
lc++;
}
else
{
lr++;
}
int tfr = fr;
int tlr = lr;
int tlc = lc;
int tfc = fc;
while (tfr >= tlr && tfc <= tlc)
{
System.out.print(a[tfr][tfc] + " ");
tfr--;
tfc++;
}
System.out.println("\n");
}
}
}
答案 6 :(得分:0)
以下是代码:
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;
}
}
}
}
答案 7 :(得分:0)
正如Alex在这里提到的,你需要在循环中查看索引。 以下是我如何解决这个问题。
Input:
a b c ----- (0,0) (0,1) (0,2)
d e f ----- (1,0) (1,1) (1,2)
g h i ----- (2,0) (2,1) (2,2)
Output:
a ----- (0,0)
b d ----- (0,1) (1,0)
c e g ----- (0,2) (1,1) (2,0)
f h ----- (1,2) (2,1)
i ----- (2,2)
public class PrintDiagonal{
public static void printDR(String[][] matrix, int rows, int cols){
for(int c=0; c < cols; c++){
for(int i=0, j=c; i< rows && j>=0;i++,j--){
System.out.print(matrix[i][j] +" ");
}
System.out.println();
}
for(int r =1; r < rows; r++){
for(int i =r, j= cols -1; i<rows && j>=0; i++,j--){
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args){
String[][] matrix ={
{"a","b","c"},
{"d","e","f"},
{"g","h","i"}
};
int rows = matrix.length;
int columns = matrix[0].length;
printDR(matrix ,rows, columns);
}
}
答案 8 :(得分:0)
这是:
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();
}
第一个循环打印从第一列开始的对角线,第二个循环打印剩余的对角线(从底行开始)。
输出:
1
4 2
7 5 3
8 6
9
答案 9 :(得分:0)
String ar[][]={{"a","b","c"},{"d","e","f"},{"g","h","i"}};
int size1=ar.length-1, size2=ar.length;
for(int i=0; i<ar.length; i++)
{
String a="";
for(int j=0, x=ar.length-1-i; j<ar.length-i; j++, x--)
{
if((j+x)==size1)
a=a+ar[x][j];
}
size1--;
System.out.println(a);
a="";
for(int j=i+1, x=ar.length-1; j<ar.length; j++, x--)
{
if((j+x)==size2)
a=a+ar[x][j];
}
System.out.println(a);
size2++;
}
GEC HF D b 一世 一个
答案 10 :(得分:0)
类型1:我们可以很轻松地使用python解决此问题
代码:
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])
输出:
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
答案 11 :(得分:-2)
这与leoflower在这里发布的内容相同。我刚刚更改了变量名称以便更好地理解。
level =表示正在打印的对角线的当前级别。例如: - level = 2表示具有索引(0,2),(1,1),(2,0)
的对角元素currDiagRowIndex =表示正在打印的当前对角线的行索引
currDiagColIndex =表示正在打印的当前对角线的列索引
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();
}
}
输入:
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
输出:
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