repetitivos - ejercicios de ciclos anidados
¿Cómo romper con los bucles anidados? (13)
Creo que goto
va a resolver el problema.
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
goto end;
}
}
}
end:
stmt2
Si utilizo una instrucción break
, solo romperá el bucle interno y necesito usar alguna bandera para romper el bucle externo. Pero si hay muchos bucles anidados, el código no se verá bien.
¿Hay alguna otra manera de romper todos los bucles? (Por favor no use goto stmt
.)
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; j++) {
if(condition) {
// both of the loops need to break and control will go to stmt2
}
}
}
stmt2
Necesitarás una variable booleana, si quieres que sea legible:
bool broke = false;
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
broke = true;
break;
}
}
if (broke)
break;
}
Si desea que sea menos legible puede unirse a la evaluación booleana:
bool broke = false;
for(int i = 0; i < 1000 && !broke; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
broke = true;
break;
}
}
}
Como forma definitiva puede invalidar el bucle inicial:
for(int i = 0; i < size; i++) {
for(int j = 0; j < 1000; i++) {
if (condition) {
i = size;
break;
}
}
}
No, no arruines la diversión con un break
. Este es el último uso válido restante de goto
:)
Si no es así, podría usar indicadores para romper los bucles anidados profundos.
Otro enfoque para salir de un bucle anidado es dividir ambos bucles en una función separada y regresar de esa función cuando quiera salir.
Resumido - para romper los bucles anidados:
- usar
goto
- usar banderas
- factorizar bucles en llamadas de función separadas
No se pudo resistir a no incluir xkcd aquí :)
Los Goto se consideran dañinos, pero como muchas personas en los comentarios sugieren que no es necesario. Si se usa juiciosamente puede ser una gran herramienta. Cualquier cosa usada con moderación es divertida.
Precaución: Esta respuesta muestra una construcción verdaderamente oscura.
Si está utilizando GCC, echa un vistazo a esta biblioteca . Al igual que en PHP, break
puede aceptar el número de bucles anidados que desea salir. Puedes escribir algo como esto:
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; j++) {
if(condition) {
// break two nested enclosing loops
break(2);
}
}
}
Qué pasa:
if(condition) {
i = j = 1000;break;
}
Si necesita los valores de i y j, esto debería funcionar pero con menos rendimiento que otros
for(i;i< 1000; i++){
for(j; j< 1000; j++){
if(condition)
break;
}
if(condition) //the same condition
break;
}
Una forma es poner todos los bucles anidados en una función y regresar desde el bucle más interno en caso de que sea necesario romper todos los bucles.
function()
{
for(int i=0; i<1000; i++)
{
for(int j=0; j<1000;j++)
{
if (condition)
return;
}
}
}
Utilice este sabio consejo del equipo de LLVM:
"Convierta los bucles de predicado en funciones de predicado"
Ver:
http://llvm.org/docs/CodingStandards.html#turn-predicate-loops-into-predicate-functions
bool stop = false;
for (int i = 0; (i < 1000) && !stop; i++)
{
for (int j = 0; (j < 1000) && !stop; j++)
{
if (condition)
stop = true;
}
}
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if(condition) {
func(para1, para2...);
return;
}
}
}
func(para1, para2...) {
stmt2;
}
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; i++) {
if(condition) {
goto end;
}
}
end:
i = 0;
do
{
for (int j = 0; j < 1000; j++) // by the way, your code uses i++ here!
{
if (condition)
{
break;
}
}
++i;
} while ((i < 1000) && !condition);
int i = 0, j= 0;
for(i;i< 1000; i++){
for(j; j< 1000; j++){
if(condition){
i = j = 1001;
break;
}
}
}
Romperá los dos bucles.