假设您要循环from i=0 to i=n and j=0 to j=m
和m!=n
。是否可以将以下两个循环缩短为一个?
for(int i=0; i<=n; i++){}
for(int j=0; j<=m; j++){}
沿着
for(int i=0,j=0; i<=n, j<=m; i++, j++){}
本质上,我希望循环说“将i和j递增1,如果i = n,则停止递增i,但如果m> n,则停止递增j”,或者如果n>m
则反之亦然。
可能看似琐碎或愚蠢,但我很好奇。
答案 0 :(得分:3)
天真地,我们想做类似的事情:
for(int i = 0, j = 0; i <= n || j <= m; i = Math.min(n, i+1), j = Math.min(m, j+1))
...但这不会终止,因为i
的最大值为n
,j
的最大值为m
,其中一个永远都是真的。
如果您愿意(n < m
)i
完成n+1
,问题会更加简单,我们可以写一下:
for(int i = 0, j = 0; i <= n || j <= m; i = Math.min(n+1, i+1), j = Math.min(m+1, j+1))
只有当n < m
} i = n
完成j
时才会保持这种情况很复杂。复杂性被隔离以使循环在正确的时间终止,同时仍允许j
完成递增。
要使循环终止,我们希望将较大的数字增加一步超过其最大值,以便我们达到终止条件。由于我们知道i <= n
和j <= m
中至少有一个将永远为真,所以让我们专注于使两者始终为真,并将终止条件更改为
i <= n && j <= m
如果n < m
,i
将在j
之前完成递增,那么我们需要让j
增加一个超过其有效最大值才能违反i <= n && j <= m
{1}}。类似的条件适用于n > m
,但相反,我们需要将i
增加一个n
。
请注意,如果n == m
,我们可以安全地增加两个超过各自限制的一个,并且终止条件将同时命中。下面的循环处理任何正输入n
或m
并在给定条件的情况下正确终止,同时允许n
或m
中的较小者成为相应迭代器的最大值。
for(int i = 0, j = 0, nadj = n + (n >= m ? 1 : 0), madj = m + (m >= n ? 1 : 0)
i <= n && j <= m;
i = Math.min(nadj, i+1), j = Math.min(madj, j+1))
值得注意的是,我们在第一部分中计算nadj
和madj
,以避免在每次迭代中重新计算它们。
答案 1 :(得分:2)
修改
for(int i=0,j=0; i+1<=n || j+1<=m; ){
if(i<n) i++;
if(j<m) j++;
// do stuff here
// keep in mind that i and j starts from 1
}
小提琴:http://jsfiddle.net/nilgundag/4frCG/
旧答案:
for(int i=0,j=0; i<=n || j<=m; ){
if(i<=n) i++;
if(j<=m) j++;
// do stuff here
// keep in mind that i and j starts from 1
}
答案 2 :(得分:1)
你可以只使用一个迭代器,因为你每次都将i和j递增1。
for(int i=0; i<=n || i<=m;i++ ){
if(i<=n) //{do first loop job}
if(i<=m) //{do second loop job}
}
答案 3 :(得分:0)
C ++:
for (int i=0, j=0; j<=m || i<=n; i+=i<=n, j+=j<=m ){}
JAVA:
for (int i=0, j=0; j<=m || i<=n; i+=(i<=n)?1:0, j+=(j<=m)?1:0 ){}