如何将两个FOR组合成一个

时间:2009-05-26 10:16:54

标签: java

这可能是愚蠢的,但我想知道是否可能,让我们从5x5矩阵开始

int[][] x = new int[5][5];      
Random rg = new Random();

现在让我们用伪随机信息填充它

for(int i=0;i<5;i++){
    for(int j =0; j<5;j++){
        x[i][j] = rg.nextInt(); 
    }           
}

但是我怎么能用一个单一来做到这一点?

for(int i=0, j=0; i<5; (j==5?i++, j=0:j++){
    x[i][j] = rg.nextInt();
}

这不起作用:(

7 个答案:

答案 0 :(得分:25)

您需要从单个索引计算行和列,然后:

for(int i = 0; i < 5 * 5; i++)
{
   int row = i / 5;
   int column = i % 5;
   x[row][column] = rg.nextInt();
}

使用/和%是经典的,这里:当您迭代矩阵的索引时,除法用于确定您所在的行。剩下的(%)就是列。

这个华丽的ASCII艺术展示了1维索引如何位于2D矩阵中:

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

应该清楚的是,对于第一行中的任何值,该值除以5是行索引本身,即它们都是0。

答案 1 :(得分:8)

你真的不会从中获得任何好处。 保持代码可读性。它实际上更加密集,进行乘法和除法建议然后只是循环。 (乘法除法和mod实际上是ALU中一组复杂的指令)

答案 2 :(得分:2)

另一种方法是:

int i,j;
for (i=0,j=0; i<5 && j<5; i = (i==4 ? 0 : i+1), j = (i==4 ? j+1 : j))
{
   x[i][j] = rg.nextInt();
}

虽然,我更喜欢放松解决方案。

答案 3 :(得分:0)

我很好奇并做了一个基准。

对于Linux上的Suns HotSpot 64服务器jvm,嵌套循环和展开的循环或多或少同样快,并且几乎与在[size * size]的线性数组上进行迭代一样快。解包的循环,其实际上比嵌套循环慢,可能是因为它做了更多的数学运算。

但是,在Windows上的IBMs jdk 1.5 32位上,嵌套循环速度慢了10倍。

虽然,我不确定它的编译器或jvm在这种情况下是否重要,但较慢的测试是使用IBM的RAD编译的,它比eclipse 3.4早了一年

因此,如果您陷入使用旧jvm和编译器的“企业”平台,那么使用这些优化来搞乱您的代码的唯一原因就是它真的非常重要。

答案 4 :(得分:0)

一旦热点编译器运行几次,嵌套循环将非常快。 见this excellent article for an explanation

答案 5 :(得分:0)

最短的解决方案

int i = 0,j=0;
 for(;j<5;j+=i==4?1:0,i++){
    if(i==5)
       i=0;
    x[j][i] = rg.nextInt();

  }

答案 6 :(得分:-1)

 int q = 5, r= 5;
 int [][] x = new int [q][r]

for(int i = 0, i < q * r, i++)
{
    int xaxis = i / q;
    int yaxis = i % r;

    x[xaxis][yaxis] = rg.nextInt();
}

虽然我不知道你为什么要...但你仍然有相同的迭代次数 这是恕我直言,更难以阅读,需要更多的数学计算才能运行,所以如果你对它进行分析它可能会慢一些