我一次又一次遇到的是嵌套循环,搜索一些2D数组以找到一个元素(通常是一些对象),然后必须对其进行 *** 作.所以当然,一旦你找到那个对象,就应该打破这两个循环,这样你就不必不必要地继续搜索你已经找到的东西(特别是在可以遍历指数巨大数组的嵌套循环中).
以下代码是我目前的首选方式:
Obj O = null;bool KeepLooPing = true;for (int j = 0; j < height && KeepLooPing; j++){ for (int i = 0; i < wIDth; i++) { if (ObjArray[i,j] != null && ObjArray[i,j].property == search_value) { O = ObjArray[i,j]; // you found it,Now remember it KeepLooPing = false; // clear the flag so the outer loop will break too break; } }}
感谢Erik Funkenbusch,如果我们这样做,它会变得更加优雅:
Obj O = null;for (int j = 0; j < height && O == null; j++) // much,much better IDea to check O for null in the outer loop{ for (int i = 0; i < wIDth; i++) { if (ObjArray[i,Now remember it break; } }}
不再需要那个讨厌的额外布尔值!
然而,寻求替代或更好的解决方案仍在继续.这些年来,我尝试了很多其他的方法,但发现它们并不是因为某种原因而变得那么好:
>将j(外循环迭代器)设置为高于高度的值,这将触发它自动中断.不理想,因为有时你想记住你发现它的i和j值.
>在2D阵列上使用foreach.不太理想,因为foreach不会让你 *** 纵集合(删除或添加它,这通常是我搜索对象的原因).
>只需将2个循环放在一个除了查找并返回O之外什么都不做的函数中.返回有效地打破了两个循环.很多时候这没关系,但并非总是如此.我这样做是为了非常通用的搜索,但也有很多“群组搜索”,我想集体化遍历.在这些情况下,我找到2个或更多的对象(有时在同一个2D数组中),记住它们,然后才会中断两个循环.
>使用转到? (哇,这可能是goto的唯一合法使用吗?它比KeepLooPing标志更具可读性,特别是如果我们有3个或更多循环.)不理想,因为同事会尖叫血腥谋杀.在C#中,goto之后会有正确的垃圾清理吗?
>抛出自定义异常? IDk,我从未尝试过,但它看起来不像我目前喜欢的方式.
>一旦找到了正确的对象,在内部循环中进行所有对象 *** 作,然后返回;这可能会很快变得凌乱.有时,对象 *** 作涉及自己的循环.
由于User_PWY,还有一个非常聪明的第7种方式:
int size = wIDth*height; // save this so you dont have to keep remultiplying it every iterationfor (int i = 0; i < size; i++){ int x = i % wIDth; // ingenIoUs method here int y = i / wIDth; // ingenIoUs method here O = ObjArray[x,y]; if (O != null) break; // woohoo!}
这有效地将2D阵列压缩成一个用于迭代的循环.然而,一些批评指出,与i或j相比,mod和除法运算符相当缓慢,因此它可能会更慢(请记住我们正在处理谁知道什么大小的2D数组).就像我评论的那样,应该有一种方法可以在一次 *** 作中得到除法和余数,因为我非常确定x86汇编代码具有div *** 作码,它将商和余数存储在单独的寄存器中,所有这些都在一个div指令中.但是如何在C#中使用它,IDk.
如果C#允许你命名循环(如L1和L2)然后执行类似L1.break()的 *** 作,那将是很好的.无论你在哪个循环中.唉……用这种语言做不到. (有没有一些秘密的方法可以使用宏来做到这一点?)是否有一个C#6.0实现了这个功能?
编辑:在我看来,我判断他们的优雅和速度的解决方案.请记住,我们正在处理嵌套循环,这可能会成倍增长.额外的 *** 作或比较可能会有所不同.
好吧,好吧,告诉我你喜欢的方式,特别是如果这里没有列出的话.
解决方法for (int i = 0; i < wIDth*height; i++){ int x=i%wIDth,y=i/wIDth; //dostuff}
我喜欢这种访问2d数组的方式.
评论1)
有许多评论担心mod(%)运算符可能代价高昂,但这是我们正在讨论的整数运算,我认为它应该与其他解决方案没有区别.
评论2)
关于宏.我找不到代码但设法简单地生成了一个代码.
#define FOR2DARRAY(WIDTH,HEIGHT) \for (int i = 0,x = 0,y = 0; i < (WIDTH)*(HEIGHT); i++,x=i%(WIDTH),y=i/(HEIGHT))总结
以上是内存溢出为你收集整理的c# – 是否有一种“聪明”的方式来打破嵌套循环?全部内容,希望文章能够帮你解决c# – 是否有一种“聪明”的方式来打破嵌套循环?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)