как мы можем выйти из 4 внутренних циклов for?

Привет, я новичок в java, и моя программа имеет 4 цикла for: моя программа работает так: если b равно true, элемент будет удален из pointList, а n будет n--, и я хочу выйти из всех циклов for и прийти снова из первого цикла for, поэтому l будет l++, как я могу это сделать? с оператором break?

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);
              }
           }
       }
    }
}

person user472221    schedule 18.11.2010    source источник
comment
МОЙ БОГ! Неужели так нужно пройти? избегайте каскадных циклов ..   -  person elCapitano    schedule 18.11.2010
comment
Может быть, вы в двух словах опишите, чем вы хотите заниматься? удалить l-й элемент, если b истинно. Ваш код содержит синтаксические ошибки. Исправьте, пожалуйста, и проясните свой вопрос.   -  person khachik    schedule 18.11.2010
comment
Похоже, вы пытаетесь найти 4 элемента, которые соответствуют некоторым критериям. Если бы вы объяснили, каковы критерии, возможно, мы могли бы предложить более простой способ сделать то же самое. например возможно, сначала сортировка списка может упростить циклы.   -  person Peter Lawrey    schedule 18.11.2010
comment
+1 - Почти бесполезная ссылка, но я все равно согласен с советом.   -  person T.E.D.    schedule 18.11.2010
comment
Одним из вариантов может быть aivosto.com/project/help/pm-complexity.html, который внизу подсказывает, что вам следует попытаться предотвратить вложение петель глубиной более двух.   -  person T.E.D.    schedule 18.11.2010
comment
Из-за проблем во время выполнения и структурного поведения (и прочего) вам следует избегать каскадных циклов. Использование глубоких рекурсий может указывать на плохой дизайн вашей программы. Не может ваша функция работать без этой рекурсии? (возможно, используя функции, объекты или что-то подобное, чтобы удовлетворить ваши потребности)   -  person elCapitano    schedule 18.11.2010


Ответы (8)


Вы можете использовать помеченный перерыв как:

      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);
                    }

                }

            }
        }
    }
person codaddict    schedule 18.11.2010
comment
он разорвет только последние три цикла for, а затем он начнется с первого цикла и войдет в эти три цикла for? - person user472221; 18.11.2010
comment
Я полагаю, вы можете рассматривать любой оператор ветвления как замаскированный goto. Но у всех есть свои пределы и свое применение. Фактически, даже сам goto (конечные автоматы - это PITA). - person T.E.D.; 18.11.2010
comment
Событие didn0t знает, что в java есть помеченные разрывы: D - person RoflcoptrException; 19.11.2010

В цикле оператор break завершает внутренний цикл, а continue переходит к следующей итерации. Чтобы эти два оператора работали в цикле, отличном от внутреннего, вам необходимо использовать ярлыки. Примерно так должно работать:

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);
                        }

                    }

                }
            }
        }
person brain    schedule 18.11.2010

Взгляните на помеченный оператор break

например здесь: Ветвящиеся операторы

person eric    schedule 18.11.2010

Используйте маркированную петлю

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);
                }

            }

        }
    }
}

а затем выйти из отмеченного цикла

person stjohnroe    schedule 18.11.2010
comment
он разорвет только последние три цикла for, а затем он начнется с первого цикла и войдет в эти три цикла for? - person user472221; 18.11.2010
comment
Функционально эквивалентен таковому от Brain. В этом случае он перейдет к следующей итерации самого внешнего цикла. - person stjohnroe; 18.11.2010

Я согласен со всеми остальными ответами. Однако я хотел бы отметить, что альтернативой exit было бы просто поместить этот код в его собственную процедуру и использовать оператор return, чтобы выйти из всего этого. Ваш четырехвложенный цикл настолько сложен сам по себе, что он, вероятно, в любом случае заслуживает включения в свою собственную программу.

Я работал над заданиями Министерства обороны, которые требовали не более цикломатической сложности чем 6 для любой программы (за некоторыми исключениями). Только эта серия циклов равна 4. Если вы не можете найти более простой способ сделать это, вам действительно следует бросить их в их собственную рутину, просто чтобы сохранить рассудок бедных болванов, которые должны поддерживать этот код.

person T.E.D.    schedule 18.11.2010

Первым «быстрым и грязным» решением было бы использовать переменную stay_into_loops и изменять for циклы, например:

 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;

Однако, когда вы сталкиваетесь с такими вещами, как правило, это запах кода. Рассмотрите возможность рефакторинга кода, потому что в какой-то момент это перерастет в беспорядок.

person lorenzog    schedule 18.11.2010

Создайте для себя выход в каждом внутреннем цикле for.
Вот быстрое и безболезненное решение.

  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;                            
                }
  }

Итак, вы видите, что логическое breakout - это ваш билет для выхода из каждого внутреннего цикла, потому что он проверяется в каждом for объявлении. И он сбрасывается каждый раз, когда выполняется первая for итерация.

person BeemerGuy    schedule 18.11.2010

person    schedule
comment
взято из stackoverflow.com/questions/551578/ - person SunnyShah; 18.11.2010