Не знаю как лучше, создать отдельную тему или написать в эту....
Отдельную тему я бы назвал "Кольцевой список и простые числа"
Есть задачка на динамическую память... Необходимо составить программу, которая каждый элемент кольцевого однонаправленного списка с заглавным элементом увеличивает на 3, а затем вычеркивает те из них, которые будут простыми.
Так вот проблема в поиске простых чисел (удаление пока не трогаю, хотя оно тоже криво работает, выдает ошибку "ссылка на не существующий указатель). До 14и она работает нормально, а с 15и начинается дребедень:
1. 15 - простое, дальше правильно, 21 - опять считает простым, потом 25, потом 35, дальше не проверял...
2. Если в списке присутствует 1 (кроме случая, когда она последняя), то система проверки на простые числа вообще не работает.
Вот код:
program kos;
{$APPTYPE CONSOLE}
uses
SysUtils;
Type pe=^el; {Указатель на элемент списковой структуры}
el=record {Элемент списка}
inf:integer; {Информационное поле типа integer}
next:pe {Указатель на следующий элемент}
end;
//функция вывода на экран списка P
function vivod(p:pe):boolean;
var lastp:pe;
begin
lastp := p^.next;
while lastp <> p do
begin
Write(lastp^.inf, ' ');
lastp := lastp^.next;
end;
WriteLn(' ]');
vivod := true;
end;
Var
temp, lastp, p: pe;
i, n, k: integer;
Begin
//контроль значения количества элементов
{$I-}
Write('Vvedite kolichestvo elementov: ');
ReadLn(n);
Writeln;
while (n<=0) or (ioresult<>0) do
begin
Writeln('Kolichestvo elementov dolgno bit` celim CHISLOM, HE men`she i HE ravno `0` ');
Write('Vvedite kolichestvo elementov: ');
ReadLn(n);
Writeln;
end;
{$I+}
//построения КОС с включенным заглавным элементом
Writeln('Vvedite ', n, ' celih chisel!');
new(p);
p^.next:=p;
lastp:=p;
For i:=1 to n do
begin
new(lastp^.next);
lastp:=lastp^.next;
Write('Vvedite ',i,' element spiska: ');
ReadLn(lastp^.inf);
end;
lastp^.next:=p;
//вывод списка P на экран
Write('Spiska P = [ ');
vivod(p);
//удаление элементов, являющихся простыми числами
lastp := p^.next;
while lastp <> p do
begin
if (lastp^.inf=2) or (lastp^.inf=3) then
begin
writeln('prostie (2 ili 3) - ', lastp^.inf);
{ temp := lastp^.next;
dispose(lastp);
lastp := temp;
break; //удаление тоже криво работает }
end
else
if lastp^.inf<2 then
begin
break;
end
else
for k:=2 to trunc(sqrt(lastp^.inf)) do
if lastp^.inf mod k = 0 then
begin
break;
end
else
begin
writeln('prostie - ', lastp^.inf);
{ temp := lastp^.next;
dispose(lastp);
lastp := temp;
break; //удаление тоже криво работает }
break;
end;
lastp := lastp^.next;
end;
Write('It`s FINISH');
readln
end.
15 - простое я всегда думал что 15= 3 * 5
Ты бы читал повнимательнее (а не просто SPAM-mode включал ), тогда бы увидел, что:
Bush, проблема у тебя - вот в этом цикле:
for k:=2 to trunc(sqrt(lastp^.inf)) do
if lastp^.inf mod k = 0 then
begin
break;
end
else ... { <--- Вот тут !!! }
lastp := p^.next;
while lastp <> p do begin
if (lastp^.inf=2) or (lastp^.inf=3) then begin
writeln('prostie (2 ili 3) - ', lastp^.inf);
{
temp := lastp^.next;
dispose(lastp);
lastp := temp;
break;
}
end
else
if lastp^.inf<2 then begin
break;
end
else begin
is_simple := true;
for k:=2 to trunc(sqrt(lastp^.inf)) do
if lastp^.inf mod k = 0 then begin
is_simple := false; { <--- Нашел делитель, и выходишь }
break;
end;
{ Если делитель не был найден - то печатать сообщение о простоте числа }
if is_simple then begin
writeln('prostie - ', lastp^.inf);
{
temp := lastp^.next;
dispose(lastp);
lastp := temp;
break;
}
break;
end;
end;
lastp := lastp^.next;
end;
Спасибо volvo, теперь поиск простых чисел работает, правда если искать по одному...
А не посмотришь что не так с проходом по списку... Цифра 1 в начале списка по прежнему все сбивает, да и вааще из всего списка выписывает только первое найденное простое число...)
if is_simple then begin
writeln('prostie - ', lastp^.inf);
break; {как думаешь, какой цикл прерывается?}
Я бы сделал вот так:
program kos;
uses
SysUtils;
Type
pe=^el;
el = record
inf: integer;
next: pe;
end;
function vivod(p:pe):boolean;
var lastp: pe;
begin
lastp := p^.next;
while lastp <> p do begin
Write(lastp^.inf, ' ');
lastp := lastp^.next;
end;
WriteLn(' ]');
vivod := true;
end;
Var
T, lastp, p, pp: pe;
i, n, k: integer;
is_simple: boolean;
Begin
{$I-}
Write('Vvedite kolichestvo elementov: '); ReadLn(n);
Writeln;
while (n<=0) or (ioresult<>0) do begin
Writeln('Kolichestvo elementov dolgno bit` celim CHISLOM, HE men`she i HE ravno `0` ');
Write('Vvedite kolichestvo elementov: ');
ReadLn(n);
Writeln;
end;
{$I+}
Writeln('Vvedite ', n, ' celih chisel!');
new(p);
p^.next:=p;
lastp:=p;
For i:=1 to n do begin
new(lastp^.next);
lastp:=lastp^.next;
Write('Vvedite ',i,' element spiska: ');
ReadLn(lastp^.inf);
end;
lastp^.next:=p;
Write('start list: [ '); vivod(p);
{ inc every, 3 }
lastp := p^.next;
while lastp <> p do begin
inc(lastp^.inf, 3);
lastp := lastp^.next;
end;
write('after inc: ['); vivod(p);
lastp := p^.next;
while lastp <> p do begin
if (lastp^.inf > 0) and (lastp^.inf <= 3) then begin
if lastp^.inf > 1 then begin
writeln('prostie (2 ili 3) - ', lastp^.inf);
is_simple := true;
end;
end
else begin
is_simple := true;
for k:=2 to trunc(sqrt(lastp^.inf)) do
if lastp^.inf mod k = 0 then begin
is_simple := false;
break;
end;
if is_simple then begin
writeln('prostie - ', lastp^.inf);
end;
end;
if is_simple then begin
T := lastp;
pp := p^.next;
while pp^.next <> T do pp := pp^.next;
pp^.next := T^.next;
lastp := lastp^.next;
dispose(T);
end
else lastp := lastp^.next;
end;
write('finally: ['); vivod(p);
Write('It`s FINISH');
readln
end.