2009-05-26 26 views
3

這可能是愚蠢的,但我想知道,如果有可能,讓我們與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(); 
} 

這不工作:(

+6

是什麼使這個單一for循環的目的是什麼?無論是單一循環還是嵌套循環,您都必須迭代X * Y次。我將嵌套循環編碼爲更好的可讀性。 – 2009-05-26 10:23:19

+0

我知道2個循環是更快,更好,可讀的方式,但我對這種方式感興趣。感謝所有的快速回答 – 2009-05-26 10:29:50

回答

25

你需要計算的行和列從一個單一的指標,那麼:

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

的使用/和%是經典,在這裏:當您遍歷矩陣的索引時,該分割用於確定您正在處於哪一行,其餘(%)則是該列。

這個華麗的ASCII藝術展示了一維索引位於二維矩陣:

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

+0

但是,我認爲它不會比2層版本更快,它仍然是O(n²)的複雜性。 – 2009-05-26 10:20:43

+0

@Bishiboosh:不,我不認爲它會更快......從來沒有說過會是這樣,只是想展示如何使用一個單一的循環來完成,就像提出的原始問題一樣。 – unwind 2009-05-26 10:25:01

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

雖然我不知道你爲什麼想...你仍然有相同的迭代次數 ,這是恕我直言,更難以閱讀,需要更多的數學計算才能運行,所以它可能會更慢,如果你剖析它

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

雖然,我更喜歡unwind的解決方案。

8

你真的不會因此而獲益。 保持您的代碼可讀。實際上,乘法和分割解決方案實際上是更密集的,然後建議循環。 (乘除和mod實際上是ALU中一組複雜的指令)

0

我很好奇,做了一個基準測試。

對於Linux上的Suns HotSpot 64服務器jvm,嵌套循環和展開循環都快或慢,而且幾乎與迭代[size * size]的線性數組一樣快。展開的循環比嵌套循環慢,可能是因爲它會做更多的數學運算。

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

雖然,我不知道,如果它的編譯器或在這種情況下重要的,較慢的測試編譯使用IBM的RAD至極的JVM是一些今年比日食3.4

所以,唯一的原因搞亂舊的如果你用一箇舊的jvm和編譯器固定在一個「企業」平臺上,那麼你的代碼將會實現這些優化,而且它確實非常重要。

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

    }