Помощь - Поиск - Пользователи - Календарь
Полная версия: Зацикливание
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Artem7
Вот написал программу для нахождения 4 совершенных чисел на отрезке, но почему то когда ввожу 1000 то происходит зацикливание (возможно и в других случаях просто не проверял больше)

Program sovershenie;
Var n,i,k,j,s:longint;
Begin
    write('Введите n= ');readln(n);
    While k<>4 do
    Begin
    For i:=2 to n do
    Begin
    s:=0;
    For j:=1 to n do
    if (i mod j = 0)and(i<>j) then s:=s+j;
    if s=i then begin writeln('Совершенное число = ',i);k:=k+1;end;
    end;
    end;
    readln;
End.
IUnknown
А что, K при каких-то условиях станет равно 4, чтобы выйти из цикла? Не станет, в интервале 2 .. 1000 всего 3 совершенных числа. Вот цикл и будет крутиться вечно, в попытках найти четвертое, несуществующее... Зачем тебе вообще цикл While - непонятно. Убери его.

P.S. Этот алгоритм поиска совершенных чисел подходит только для небольших интервалов. Чем интервал шире - тем дольше будет осуществляться поиск. Тогда совершенные числа стоит искать вот так
Artem7
Цитата(IUnknown @ 16.03.2012 12:33) *

А что, K при каких-то условиях станет равно 4, чтобы выйти из цикла? Не станет, в интервале 2 .. 1000 всего 3 совершенных числа. Вот цикл и будет крутиться вечно, в попытках найти четвертое, несуществующее... Зачем тебе вообще цикл While - непонятно. Убери его.

P.S. Этот алгоритм поиска совершенных чисел подходит только для небольших интервалов. Чем интервал шире - тем дольше будет осуществляться поиск. Тогда совершенные числа стоит искать вот так

В том то и дело что мне преподаватель сказал ввести счётчик чтобы заканчивался когда 4 совершенных найдёт...так без него конечно корректнее всё было бы...

Добавлено через 3 мин.
Спасибо терь всё понятно стало почему зацикливается)))пусть так и будет раз ему так надо)))Спасибо)))
TarasBer
> В том то и дело что мне преподаватель сказал ввести счётчик чтобы заканчивался когда 4 совершенных найдёт...

Ты его не туда поставил. У тебя сначала перебираются ВСЕ числа до эн, а потом проверяется счётчик. А надо проверять его постоянно:

For i:=2 to n do
Begin
    s:=0;
    For j:=1 to n do
      if (i mod j = 0)and(i<>j) then s:=s+j;
    if s=i then begin 
      writeln('Совершенное число = ',i);
      k:=k+1;
      if k>=4 then Break; // достигли порога - выходим из цикла
    end;
end;

Artem7
Цитата(TarasBer @ 16.03.2012 13:35) *

> В том то и дело что мне преподаватель сказал ввести счётчик чтобы заканчивался когда 4 совершенных найдёт...

Ты его не туда поставил. У тебя сначала перебираются ВСЕ числа до эн, а потом проверяется счётчик. А надо проверять его постоянно:

For i:=2 to n do
Begin
    s:=0;
    For j:=1 to n do
      if (i mod j = 0)and(i<>j) then s:=s+j;
    if s=i then begin 
      writeln('Совершенное число = ',i);
      k:=k+1;
      if k>=4 then Break; // достигли порога - выходим из цикла
    end;
end;



Спасибо но я замутил вот так
Program sovershenie;
Var n,i,k,j,s:longint;
Begin
    write('Введите n= ');readln(n);
    While k<4 do
    Begin
    For i:=2 to n do
    Begin
    s:=0;
    For j:=1 to n do
    if (i mod j = 0)and(i<>j) then s:=s+j;
    if (s=i)and(k<4) then begin writeln('Совершенное число = ',i);k:=k+1;end;
    end;
    end;
    readln;
End.

TarasBer
> Спасибо но я замутил вот так

Фигню ты замутил. Зависон на случай, если чисел до эн меньше 4, никуда не делся.
Artem7
Цитата(TarasBer @ 17.03.2012 12:14) *

> Спасибо но я замутил вот так

Фигню ты замутил. Зависон на случай, если чисел до эн меньше 4, никуда не делся.

никого зависона если что опять же идёт по новому проверка и выдаёт те же совершенные числа что и нашёл до этого....лучше всматриваться в прогу надо было)
TarasBer
Цитата(Artem7 @ 17.03.2012 13:33) *

никого зависона если что опять же идёт по новому проверка и выдаёт те же совершенные числа что и нашёл до этого....лучше всматриваться в прогу надо было)

А, ну да, извини. Но он выводит те же числа снова, ты считаешь это корректным?
Это в любом случае ты написал неверный алгоритм.
Artеm
да он станет верным тогда когда уберешь ограничение в 4 а просто вывод того сколько в диапозоне :-)
TarasBer
> да он станет верным тогда когда уберешь ограничение в 4 а просто вывод того сколько в диапозоне :-)

Твой код не подходит под техзадание. Отмазы типа "оно будет верным под другое ТЗ" никому не интересны.
Artеm
Цитата(TarasBer @ 17.03.2012 17:37) *

> да он станет верным тогда когда уберешь ограничение в 4 а просто вывод того сколько в диапозоне :-)

Твой код не подходит под техзадание. Отмазы типа "оно будет верным под другое ТЗ" никому не интересны.

ну если подумать то как он подойдет если например я введу число n равное 100 то там всего 2 совершенных числа то как тогда должна программа найти еще 2?
IUnknown
Цитата
если например я введу число n равное 100 то там всего 2 совершенных числа то как тогда должна программа найти еще 2?
Да не должна она искать еще 2... Программа должна вывести МАКСИМУМ 4 совершенных числа (если четырех нет - то вывести ровно столько, сколько есть), а не из любого интервала высасывать 4 штуки, даже если их там совсем нет. Для интереса попробуй ввести n = 5, посмотрим, откуда тогда твой код найдет 4 совершенных числа.
Artem7
Цитата(IUnknown @ 18.03.2012 12:25) *

Да не должна она искать еще 2... Программа должна вывести МАКСИМУМ 4 совершенных числа (если четырех нет - то вывести ровно столько, сколько есть), а не из любого интервала высасывать 4 штуки, даже если их там совсем нет. Для интереса попробуй ввести n = 5, посмотрим, откуда тогда твой код найдет 4 совершенных числа.

Ну если только так то тогда будет вот так
Program sovershenie;
Var n,i,k,j,s:longint;
Begin
    write('Введите n= ');readln(n);
    For i:=2 to n do
    Begin
    s:=0;
    For j:=1 to n do
    if (i mod j = 0)and(i<>j) then s:=s+j;
    if (s=i) then begin writeln('Совершенное число = ',i);k:=k+1;end;
    if k>=4 then break;
    end;
    if k=0 then writeln('Совершенных чисел нету в данном диапозоне');
    readln;
End.

TarasBer
Во, теперь верно написал.
Artem7
Спасибо всем за помощь)))просто не правильно понял постановку задачи)))
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.