简体   繁体   English

如何将两个 FOR 合二为一

[英]How to combine two FORs into one

This might be stupid, but I'm want to know if it's possible, lets start with 5x5 a matrix这可能很愚蠢,但我想知道是否可能,让我们从 5x5 矩阵开始

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

now let's fill it with Pseudo Random information现在让我们用伪随机信息填充它

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

but how can I do this right with one Single for?但是我怎么能用一个 Single for 做到这一点呢?

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

this is not working :(这不起作用:(

You need to compute the row and column from a single index, then:您需要从单个索引计算行和列,然后:

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

The use of / and % is classic, here: as you iterate over the indices of the matrix, the division is used to figure out which row you're on. / 和 % 的使用是经典的,在这里:当您迭代矩阵的索引时,除法用于确定您所在的行。 The remainder (%) is then the column.余数 (%) 则是该列。

This gorgeous ASCII art shows how the 1-dimensional indices are located in the 2D matrix:这个华丽的 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

It should be clear that for any value in the first row, that value divided by 5 is the row index itself, ie they're all 0.应该清楚的是,对于第一行中的任何值,该值除以 5 就是行索引本身,即它们都是 0。

You really will not gain anything from doing that.你真的不会从中得到任何好处。 keep your code readable .保持你的代码可读 it's actually more intensive to do the multiplications and divisions unwind suggested then to just to a loop.实际上,将建议的乘法和除法展开到循环中实际上更加密集。 (multiply divide and mod are actually a complex set of instructions in an ALU) (乘除法和mod实际上是ALU中的一组复杂指令)

Another way to do it would be:另一种方法是:

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();
}

Although, I prefer unwind's solution.虽然,我更喜欢放松的解决方案。

Shortest solution最短解

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

  }

I got curious and did a benchmark.我很好奇并做了一个基准测试。

For Suns HotSpot 64 server jvm on Linux, both nested loops and unwrapped loops were more or less equally fast, and almost as fast as iterating over a linear array of [size*size].对于 Linux 上的 Suns HotSpot 64 服务器 jvm,嵌套循环和解包循环或多或少同样快,几乎与迭代 [size*size] 的线性数组一样快。 The unwrapped loop where infact slowe than the nested loop, probably because it does some more math.展开的循环实际上比嵌套循环慢,可能是因为它做了更多的数学运算。

However, On IBMs jdk 1.5 32 bit on Windows, the nested loop is more than 10x slower.但是,在 Windows 上的 IBM jdk 1.5 32 位上,嵌套循环要慢 10 倍以上。

Though, I am not sure if its the compiler or the jvm that matters in this case, the slower test was compiled using IBMs RAD wich is some year older than eclipse 3.4虽然,我不确定在这种情况下是编译器还是 jvm 重要,但较慢的测试是使用 IBM 的 RAD 编译的,比 eclipse 3.4 早一些年

So the only reason to mess up your code with these optimizations would be if you are stuck on an "enterprisy" platform with an old jvm and and compiler, and it's really really time critical.因此,使用这些优化弄乱您的代码的唯一原因是,如果您被困在带有旧 jvm 和编译器的“企业”平台上,这真的非常关键。

一旦热点编译器运行它们几次,嵌套循环将非常快......请参阅这篇出色的文章以获取解释

 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();
}

Though I don't know why you'd want to... you still have the same number of iterations and this is IMHO more difficult to read and requires more mathematical calculations to run, so it's probably slower if you profile it虽然我不知道你为什么想要......你仍然有相同的迭代次数,恕我直言,这更难阅读并且需要更多的数学计算来运行,所以如果你分析它可能会更慢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM