c# – 是否有一种“聪明”的方式来打破嵌套循环?

c# – 是否有一种“聪明”的方式来打破嵌套循环?,第1张

概述(现在我主要使用C#.欢迎其他语言的想法,但如果可以,请将它们翻译成C#,并且要明确.) 我一次又一次遇到的是嵌套循环,搜索一些2D数组以找到一个元素(通常是一些对象),然后必须对其进行 *** 作.所以当然,一旦你找到那个对象,就应该打破这两个循环,这样你就不必不必要地继续搜索你已经找到的东西(特别是在可以遍历指数巨大数组的嵌套循环中). 以下代码是我目前的首选方式: Obj O = null;boo (现在我主要使用C#.欢迎其他语言的想法,但如果可以,请将它们翻译成C#,并且要明确.)

我一次又一次遇到的是嵌套循环,搜索一些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的唯一合法使用吗?它比KeepLo​​oPing标志更具可读性,特别是如果我们有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# – 是否有一种“聪明”的方式来打破嵌套循环?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1219605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存