Чтобы преобразовать цикл for в цикл do.. while - PullRequest
0 голосов
/ 11 мая 2018

Я наткнулся на программу для печати всех простых чисел от 1 до n, где 'n' - это значение, предоставленное пользователем. Он использовал цикл for. Программа выглядит следующим образом -

#include <stdio.h>

int main()
{
    int i, j, end, isPrime; // isPrime is used as flag variable

    /* Input upper limit to print prime */
    printf("Find prime numbers between 1 to : ");
    scanf("%d", &end);

    printf("All prime numbers between 1 to %d are:\n", end);

    /* Find all Prime numbers between 1 to end */
    for(i=2; i<=end; i++)
    {
        isPrime = 1; 
        for(j=2; j<=i/2; j++)
        {
            if(i%j==0)
                isPrime = 0;
        }
        if(isPrime==1)
        {
            printf("%4d", i);
        }
    }
    return 0;
}

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

#include <stdio.h>
main()
{
    int i, j, n, isPrime;
    printf("Enter n\n");
    scanf ("%d", &n);
    i = 2;

    do 
    {
        do
        {
            j = 2;
            if (i%j == 0)
                isPrime = 0;
            else
            {
                isPrime = 1;
                printf ("%d", i);
            }
            j = j+1;
        }
        while (j <= i/2);

        i = i+1;
    }
    while (i <= n);
}

Ответы [ 4 ]

0 голосов
/ 11 мая 2018

A для цикла

for (INIT; CONDITION; NEXT) {
    BODY;
}

эквивалентно циклу while

{
    INIT;
    while (CONDITION) {
        BODY;
        NEXT;
    }
}

(за исключением того, что цикл for не позволяет объявлять одно и то же имя в INIT и во внешнем блоке BODY).

Вы допустили пару ошибок при конвертации:

  1. Синтаксис do { BODY; } while (CONDITION); всегда выполняет BODY хотя бы один раз. Исходный цикл for может не выполняться.

Это имеет значение для случая i==2: в исходном коде внутренний цикл for установит j=2, а затем сразу же проверит, является ли j<=i/2, что равно 2<=1, или ложно, поэтому тело цикла выиграло не выполняется вообще. Но ваш код начинается с установки i=2; j=2;, а затем идет прямо к тесту коэффициента if (i%j == 0). Это правда, поэтому он неправильно заключает, что 2 не является простым числом.

  1. Вы переместили операторы isPrime = 1; и printf из внешнего цикла на i, чтобы быть внутри внутреннего цикла на j. Это плохо изменяет поведение программы.

Рассмотрим, что происходит, когда i==15: мы начинаем с j=2 и обнаруживаем, что i%j != 0, поскольку 2 не является фактором 15. Таким образом, он устанавливает isPrime = 1; и печатает 15. Внутренний цикл продолжается, установив j=3. На этот раз i%j == 0, поскольку 3 имеет коэффициент 15, поэтому он устанавливает isPrime = 0; и ничего не печатает. Внутренний цикл повторяется с j=4. Теперь он вернулся к i%j != 0, поэтому устанавливает isPrime = 1; и печатает 15 снова. Это продолжается до j=7, печатая 15 всего четыре раза (когда j равно 2, 4, 6 и 7).

Я оставлю это вам, чтобы посмотреть, сможете ли вы исправить код, используя while loop.

0 голосов
/ 11 мая 2018

Попробуйте вместо этого код:

#include <stdio.h>
main(){
int i, j, n, isPrime;
printf("Enter n\n");
scanf ("%d", &n);
i = 2;
do 
{
    isPrime = 1;

    j = 2;

    do
    { 
        if (i%j == 0 && j <= i/2)
            isPrime = 0;
        j = j+1;
    }
    while (j <= i/2);

    if(isPrime == 1) printf ("%d\n", i);

    i = i+1;
}
while (i <= n);
}

Трудно перевести цикл for в цикл do-while.

Например, с проблемами, которые у вас были в коде:

  • В начале второго цикла do вы устанавливали j на 2, снова и снова. Это означало, что вы застряли в бесконечном цикле, так как в начале цикла значение j будет сброшено.
  • isPrime должен быть установлен как 1 в начале первого цикла do-while. Это так, что если i равно в любой точке , кратное j, флаг устанавливается в 0, что означает, что i не является простым. Проблема с тем, как вы устанавливаете его, заключается в том, что если последнее значение j НЕ делится на i, тогда isPrime устанавливается в 1, , даже если предыдущие значения j делятся на него .
0 голосов
/ 11 мая 2018

вот код, который вам нужен.

#include <stdio.h>
main() {
  int i, j, n, isPrime;
  printf("Enter n\n");
  scanf("%d", &n);
  i = 2;
  do {
    j = 2;
    isPrime = 1;
    if (i == 2)
      printf("%d ", i);
    do {
      if (i % j == 0) {
        isPrime = 0;
        break;
      }
      j = j + 1;
    } while (j <= i / 2);
    if (isPrime)
      printf("%d ", i);
    i = i + 1;
  } while (i <= n);
}
0 голосов
/ 11 мая 2018

Вы хорошо начали, но допустили несколько небольших ошибок, которые привели к большим проблемам

j=2 было установлено во втором цикле do-while.Это привело к тому, что j был установлен в 2 в каждом цикле, таким образом, никогда не выходя из цикла do while.

Следующим было if / else.В примере цикла for if (isPrime==1) находился вне цикла for.Вы проверяли внутри цикла while, в результате чего вещи были названы простым способом в ближайшее время.

Ниже приведен пример рабочего кода

#include <stdio.h>
main()
{
    int i, j, n, isPrime;
    printf("Enter n\n");
    scanf ("%d", &n);
    printf("All prime numbers between 2 to %d are:\n", n);

    i = 2;
    do 
    {
        isPrime = 1;
        j = 2;

        do
        {
            if (i%j == 0)
                isPrime = 0;
            j = j+1;
        } while (j < i/2);

        if (isPrime == 1 || i == 2)
            printf ("%d\n", i);
        i = i+1;
    }
    while (i <= n);
}
...