¿Cómo podemos salir de 4 bucles for internos?
-
26-09-2019 - |
Pregunta
Hola, soy principiante en Java y mi programa tiene 4 para bucles:mi programa funciona asi que si b
es true
, el elemento será eliminado de pointList y n
será n--
y quiero salir de todos los bucles for y volver desde el primer bucle for, así que l
será l++
,Cómo puedo hacer esto ?con declaración de ruptura?
for (int l = 0; l < n; l++) {
for (int i = 1; i < (n - 2); i++) {
for (int j = i + 1; j < (n - 1); j++) {
for (int k = j + 1; k < n; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
break;
}
else
System.out.println(b);
}
}
}
}
}
Solución
Se puede hacer uso de un descanso etiquetado como:
for (int l = 0; l < n; l++) {
foo: for (int i = 1; i < (n - 2); i++) {
for (int j = i + 1; j < (n - 1); j++) {
for (int k = j + 1; k < n; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
break foo;
}
else
System.out.println(b);
}
}
}
}
}
Otros consejos
En un bucle de la declaración break
termina el bucle interior mientras continue
salta a la siguiente iteración. Para que estas dos afirmaciones para trabajar en un circuito diferente a la interior que necesita para su uso etiquetas . Algo como esto debería funcionar:
outerloop:
for (int l = 0; l < n; l++) {
for (int i = 1; i < (n - 2); i++) {
for (int j = i + 1; j < (n - 1); j++) {
for (int k = j + 1; k < n; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
continue outerloop;
}
else
System.out.println(b);
}
}
}
}
}
Eche un vistazo a la declaración de interrupción etiquetada
por ejemplo aquí: Declaraciones de ramificación
String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
for(Object2 object2: object1){
//I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
//Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
//Compare with valueFromObj2 to decide either to break all the foreach loop
if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
break OUTERMOST;
}
}//fourth loop ends here
}//third loop ends here
}//second loop ends here
}//first loop ends here
Utilice un bucle etiquetado
for (int l = 0; l < n; l++) {
loopa:
for (int i = 1; i < (n - 2); i++) {
for (int j = i + 1; j < (n - 1); j++) {
for (int k = j + 1; k < n; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
break loopa;
}
else
System.out.println(b);
}
}
}
}
}
y luego salir del bucle etiquetado
again:
for (int l = 0; l < n; l++) {
for (int i = 1; i < (n - 2); i++) {
for (int j = i + 1; j < (n - 1); j++) {
for (int k = j + 1; k < n; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), pointList.get(i), pointList.get(j), pointList.get(k));
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
break again;
}
else
System.out.println(b);
}
}
}
}
}
Estoy de acuerdo con todas las otras respuestas. Sin embargo, me gustaría señalar que una alternativa a exit
sería simplemente poner ese código en su propia rutina y el uso de una declaración return
para salir de todo el asunto. El bucle de cuatro anidada es tan complejo por sí mismo que probablemente se merece estar en su propia rutina de todos modos.
He trabajado en puestos de trabajo del Departamento de Defensa que requerían una ciclomática complejidad de no más de 6 para cualquier rutina de uno (con algunas excepciones). Esta serie de bucles es solamente 4. Si no puede encontrar una manera más sencilla de hacerlo, que realmente debería tirar de ellos en su propia rutina sólo para preservar la sanidad de los idiotas pobres que tienen que mantener este código.
Una primera 'rápido y sucio' solución sería utilizar una variable stay_into_loops
y modificar los bucles for
como:
boolean stay_into_loops = true
// here goes the first for loop
for (int i = 1; i < (n - 2) && stay_into_loops ; i++) {
for (int j = i + 1; j < (n - 1) && stay_into_loops ; j++) {
for (int k = j + 1; k < n && stay_into_loops ; k++) {
if (l != i && l != j && l != k) {
boolean b = isOK(pointList.get(l), `pointList.get(i), pointList.get(j), pointList.get(k));`
System.out.println(b);
if (b == true) {
pointList.remove(pointList.get(l);
n--;
stay_into_loops = false;
break;
Sin embargo, es generalmente un olor código cuando se encuentra con cosas como estas. Considere la refactorización del código, ya que esto derivar en un desastre en algún momento.
Crear una salida por sí mismo en cada ciclo for interior.
Aquí hay una solución rápida y sin dolor.
bool breakout;
for (int l = 0; l < n; l++)
{
breakout = false;
for (int i = 1; i < (n - 2) && !breakout; i++)
for (int j = i + 1; j < (n - 1) && !breakout; j++)
for (int k = j + 1; k < n && !breakout; k++)
{
if(b == true)
breakout = true;
}
}
Así que ya ves el booleano breakout
es su boleto de salida de cada bucle interno, coz que se comprueba en cada declaración for
.
Y se pone a cero siempre que las primeras iteraciones for
.