2013-08-19 3 views
0

Нет проблем с компиляцией, но есть ли у меня цикл while или нет, результат тот же. Я не могу понять, почему включен цикл while. Кстати, это только пример программы из учебника Java SE:В следующей программе, какова цель цикла while?

public class ContinueWithLabelDemo { 

    public static void main(String[] args) { 

     String searchMe = "Look for a substring in me"; 
     String substring = "sub"; 
     boolean foundIt = false; 

     int max = searchMe.length() - substring.length(); 

     test: 
     for (int i = 0; i <= max; i++) { 
      int n = substring.length(); 
      int j = i; 
      int k = 0; 

      while (n-- != 0) { // WTF??? 
       if (searchMe.charAt(j++) != substring.charAt(k++)) { 
        continue test; 
       } 
      } 

      foundIt = true; 
      break test; 
     } 
     System.out.println(foundIt ? "Found it" : "Didn't find it"); 
    } 
} 
+3

'n' отсчитывает от' substring.length() 'до' 0' – MadProgrammer

+0

@MadProgrammer обычно да, но 'continue test;' внутри 'while' делает это не так просто ... – Pshemo

+0

@MadProgrammer I don подумайте, b/c, тогда он будет запускать этот цикл только 3 раза, но он продолжает идти до тех пор, пока подстрока не будет найдена (или нет). Кроме того, если я выберу цикл while (включая правильные фигурные скобки), результат программы будет таким же. Должна быть некоторая веская причина, по которой они вставляются. – VisWebsoft

ответ

4

Вы можете заменить ваш

while (n-- != 0) { // WTF??? 

с

System.out.println("outside loop"); 
while (n-- != 0) { // WTF??? 
    System.out.println("inside loop: comparing " 
      + searchMe.charAt(j) + ":" + substring.charAt(k)); 

, чтобы увидеть, как работает этот пример. Ниже приводится небольшое объяснение.


Этот код ищет substring в searchMe строке. Посмотрите на этот пример:

Look for a substring in me 
^ 
sub 

Если сравнивать символы в позиции 0 в searchMe и substring вы заметите, что они не одни и те же L = s поэтому мы можем пропустить соответствующие остальные буквы и перейти к следующему! положение (то есть цель continue test;)

Look for a substring in me 
^ 
sub 

Так что теперь мы попытаемся сравнить следующую букву с первой буквой searchMe с первой буквой substring. На этот раз мы получим o! = s, поэтому нет способа, чтобы подстрока начиналась в этом месте, позволяет продолжить.

После нескольких сравнений мы, наконец, нашли перспективное место

Look for a substring in me 
     ^
      sub 

где первая буква substring такая же, как в текущей буквы searchMe (s == s), поэтому мы не будем прыгать от while цикла еще и будет пытаться проверьте следующую букву. И у нас есть еще один успех

Look for a substring in me 
      ^
      sub 

u потому что == u, поэтому мы продолжим цикл, пока мы не перебирать весь наш substring, который может произойти в следующем шаге.

Look for a substring in me 
      ^
      sub 

И на этот раз мы сравнили b с b. Поскольку они равны, и у нас нет больше букв в substring, чтобы проверить, что мы можем установить значение foundIt на true и тормоз test для цикла.

И это конец.


Если удалить, а из вашего кода вы получите положительный ответ, как только вы увидите первый символ, который будет соответствовать первой букве substring в вашем случае после проверки Look for a программы будет соответствовать s с первой буквой на substring который также будет s.

Хотя цикл используется здесь для перебора по всему substring и только в случае сбоя в сопоставлении соответствующих символов мы будем перемещать поиск в одном месте вперед. Если мы будем игнорировать этот внутренний цикл и просто перебирать целые данные, мы можем игнорировать некоторые положительные результаты, как в случае, если мы будем искать aab в aaab String. Посмотрите

aaab 
aab 
^^ 

^ будет соответствовать, но после них мы должны соответствовать a с b, который потерпит неудачу. Без внутреннего цикла в то время как мы, вероятно, начать еще один матч с последней проверкой позиции, что не удалось, который был бы

aaab 
    aab 
^

На этот раз мы не смогли найти совпадение для подстроки, поэтому мы пропустили a*aab* части.