Необходимо преобразовать этот цикл в цикл while - PullRequest
1 голос
/ 28 апреля 2010

Я недавно решил проблему. Но у меня есть один кусок кода, где я не использую инициализацию цикла for и проверку условий. Это выглядит немного странно для цикла for. Я хочу преобразовать его в цикл while. Пожалуйста, помогите мне сделать это. Я пробовал много раз, но где-то чего-то не хватает.

for(;;current =(current+1)%n){
    if(eliminated[current%n]){
        continue;
    }else{
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
}

В приведенном выше коде исключено [index] - логическое значение.

Редактировать : Спасибо Джеффу, который предоставил мне решение, которое я в дальнейшем минимизировал следующим образом.

while( eliminated[current] || ++inkiPinki != m )
    current = (current+1) % n;
eliminated[current] = true;
printStatus( eliminated, people );
remainingGuys--;

Ответы [ 4 ]

2 голосов
/ 28 апреля 2010

Все циклы for можно преобразовать в циклы while, используя следующий шаблон:

for (..xxx..; ..yyy..; ..zzz..) {
  ..aaa..
}

становится

...xxx...
while (...yyy...) {
  ..aaa..
  ..zzz..
}

помните, что

for (;;) {
  ..aaa..
}

эквивалентно

for (nop; true; nop) {
  ..aaa..
}

где «nop» означает отсутствие операций.

В вашем примере это делает ваш цикл:

for(;;current =(current+1)%n){
    if(eliminated[current%n]){
        continue;
    }else{
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
}

эквивалентно

// no initialzation needed
while(true) {
    //if(eliminated[current%n]){
    //    continue;
    //}else{
    if(!eliminated[current%n]){
        inkiPinki++;
        if(inkiPinki == m){
            eliminated[current%n] = true;
            printStatus(eliminated, people);
            remainingGuys--;
            break;
        }
    }
    current =(current+1)%n;
}

Оттуда вы можете упростить его, если хотите.

1 голос
/ 28 апреля 2010

Как бы я это сделал:

while (inkiPinki < m) {
    if (!eliminated[current % n]) {
        inkiPinki++;

        if (inkiPinki == m) {
            eliminated[current % n] = true;
        }
    }

    if (inkiPinki < m) {
        current = (current + 1) % n;
    }
}

printStatus(eliminated, people);
remainingGuys--;

Этот код выполняет то же самое, что и исходный цикл for, за исключением того, что он использует логические тесты, чтобы определить, должен ли он продолжать цикл. Нет необходимости в continue или break. Если вы обнаружите, что используете одно из этих утверждений, вероятно, следует провести некоторый рефакторинг.

1 голос
/ 28 апреля 2010

Попробуйте

while( true ) {
    if( !eliminated[current] ) {
        if( ++inkiPinki == m ) {
            break;
        }
    }
    current = (current+1) % n;
}
eliminated[current] = true;
printStatus( eliminated, people );
remainingGuys--;

Это должно быть логически эквивалентно.

0 голосов
/ 28 апреля 2010

Мне кажется, что я использую логические значения в качестве целых чисел:

for (;inkiPinki<m; inkPinki += !eliminated[current])
    current = (current + 1) %n;

eliminated[current] = true;
printStatus(eliminated, people);
remainingGuys--;

Я также изменил current%n на просто current в нескольких местах, потому что %n уже сделан там, где увеличивается ток, поэтому current уже должно быть уменьшено по модулю n.

Если бы я делал это, я бы, вероятно, изменил смысл, поэтому вместо eliminated это было бы что-то вроде remaining:

for (;inkiPinki<m; inkPinki += remaining[current])
    current = (current + 1) %n;

remaining[current] = false;
printStatus(remaining, people);
remainingGuys--;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...