Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.12.2010, 03:10   #1
RAVAL(c)
Пользователь
 
Регистрация: 05.09.2010
Сообщений: 31
Вопрос простые числа (паскаль)

Здравствуйте, помогите пожалуйста.
Задача: " найти простые числа в диапазоне м н"
вот мой код:
Код:
 
var
 a,b         : array [1..100] of longint;
 i,l,m,n,p,j : longint;
begin
  readln(n,m);
  for i:=2 to m do
    if odd(i)
      then
        begin
          inc(l);
          a[l]:=i;
        end;
  p:=1;
  b[1]:=2;
  for i:=1 to l do
    begin
      if a[i]<>-1
        then
          begin
            inc(p);
            b[p]:=a[i];
            for j:=1 to l do
              if (a[j] mod a[i]=0) and (a[j]<>a[i]) and (a[j]<>-1)
                then a[j]:=-1;
          end;
    end;
  for i:=1 to p do 
    if b[i]>=n
    then writeln(b[i]);
end.
RAVAL(c) вне форума Ответить с цитированием
Старый 19.12.2010, 03:19   #2
andrewpalkin
Форумчанин
 
Аватар для andrewpalkin
 
Регистрация: 23.11.2010
Сообщений: 458
По умолчанию

И в чем проблема кода ? Вроде как все должно работать !
--- Если я вам помог , то помогите и вы мне . Не просто просите решить задачу , а пробуйте ее сами решить ! Я не пишу программы с нуля , я помогаю поправить код ! ---
andrewpalkin вне форума Ответить с цитированием
Старый 19.12.2010, 03:42   #3
RAVAL(c)
Пользователь
 
Регистрация: 05.09.2010
Сообщений: 31
Вопрос

не проходит по времени.
если вводить большой диапазон, не успевает обработать за 2секунды
RAVAL(c) вне форума Ответить с цитированием
Старый 19.12.2010, 04:35   #4
Tony Parker
Пользователь
 
Регистрация: 19.12.2010
Сообщений: 52
По умолчанию

Ваш алгоритм работает за время O(l^2) т.к. самыми долгими являются вложенные циклы по i и j от 1 до l. Это = O([n/2]^2) = O(n^2)

Есть более быстрый алгоритм за O(l*sqrt(n)) = O([n/2]*sqrt(n)) = O(n*sqrt(n)):

Код:
var
 a : array [1..100] of longint;
 i,l,m,n,j, q : longint;
begin
  readln(n,m);
  l:= 1;
  a[1]:= 2;
  for i:=2 to m do
    if odd(i) then
    begin
      inc(l);
      a[l]:=i;
    end;
  { проходим по массиву а и заменяем все не простые числа на -1 }
  for i:=1 to l do
  begin
    for j:=1 to i-1 do begin
     q:= sqrt(a[i]);
     if (a[j] > q) break; { т.к. перебираем до sqrt(a[i])}
     if (a[j]<>-1) and (a[i] mod a[j]=0)
       then a[j]:=-1;
    end;
  end;
  for i:=1 to l do 
    if a[i]>=n then writeln(a[i]);
end.
Здесь применена следующая оптимизация:
для того, чтобы число x было простым, достаточно чтобы оно не делилось нацело на все простые числа от 2 до sqrt(x). Т.к. если x - не простое, то оно представимо в виде x = a*b, где a <= b (иначе поменяем а и b местами), откуда a <= sqrt(x). Плюс от 2 до корня перебирать достаточно простые т.к. если число не простое, то оно делится на простое, меньшее его.
AllSuccess1.ru - каталог полезных курсов.

Последний раз редактировалось Tony Parker; 19.12.2010 в 04:52.
Tony Parker вне форума Ответить с цитированием
Старый 20.12.2010, 00:33   #5
RAVAL(c)
Пользователь
 
Регистрация: 05.09.2010
Сообщений: 31
По умолчанию

Tony Parker,твоя программа вообще не ищет простые числа
RAVAL(c) вне форума Ответить с цитированием
Старый 20.12.2010, 13:26   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

думаю, что тут надо применять решето Эратосфена...

кстати, а такое решение "в лоб" не проходит по времени?
Код:
function isPrime(X: longint): boolean;
var i: word;
Begin
     isPrime:=false;
     if x<2 then Exit;
     if not odd(x) and (x<>2) { проверяем на чётность  }
          then exit;
     i:=3;
     while i <= sqrt(x) do { проверяем только нечётные }
     begin
          if x mod i = 0 then Exit;
          inc(i,2);
     end;
     isPrime:=true;
End;
var  
 i,m,n : longint;
begin
   readln(n,m);
   i := n;
   if Not odd(i) then inc(i);
   while i<=m do begin
     if isPrime(i) then Writeln(i); 
     inc(i,2); 
   end; 
end.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 20.12.2010, 19:10   #7
RAVAL(c)
Пользователь
 
Регистрация: 05.09.2010
Сообщений: 31
Вопрос

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
думаю, что тут надо применять решето Эратосфена...

кстати, а такое решение "в лоб" не проходит по времени?
Код:
function isPrime(X: longint): boolean;
var i: word;
Begin
     isPrime:=false;
     if x<2 then Exit;
     if not odd(x) and (x<>2) { проверяем на чётность  }
          then exit;
     i:=3;
     while i <= sqrt(x) do { проверяем только нечётные }
     begin
          if x mod i = 0 then Exit;
          inc(i,2);
     end;
     isPrime:=true;
End;
var  
 i,m,n : longint;
begin
   readln(n,m);
   i := n;
   if Not odd(i) then inc(i);
   while i<=m do begin
     if isPrime(i) then Writeln(i); 
     inc(i,2); 
   end; 
end.

вообще-то моё решение было именно "решетом эратосфена", но видемо из-за вложеного цикла оно не проходит по времени.
вот я и спрашиваю более быструю реализацию алгоритма
RAVAL(c) вне форума Ответить с цитированием
Старый 21.12.2010, 02:01   #8
RAVAL(c)
Пользователь
 
Регистрация: 05.09.2010
Сообщений: 31
По умолчанию

??????????
RAVAL(c) вне форума Ответить с цитированием
Старый 21.12.2010, 09:59   #9
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,544
По умолчанию

Суть "решета Эратосфена" заключается в отказе от операций деления (в т.ч. и mod), всяческих проверок(кроме границ массива) и использовании быстрого прохода по массиву с заданным приращением индекса.
Код:
    j:=i;
    while j<l do begin a[j]:=-1; j:=j+b[p]; end;
//    for j:=1 to l do
//      if (a[j] mod a[i]=0) and (a[j]<>a[i]) and (a[j]<>-1) then 
//        a[j]:=-1;
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 21.12.2010 в 10:03.
evg_m вне форума Ответить с цитированием
Старый 28.12.2010, 02:41   #10
Tony Parker
Пользователь
 
Регистрация: 19.12.2010
Сообщений: 52
По умолчанию

2 RAVAL(c)

Fixed. Всё ищет. Зацениваем:

Код:
var
 a : array [1..100] of longint;
 i,l,m,n,j, q : longint;
begin
  readln(n,m);
  l:= 1;
  a[1]:= 2;
  for i:=2 to m do
    if odd(i) then
    begin
      inc(l);
      a[l]:=i;
    end;
  { проходим по массиву а и заменяем все не простые числа на -1 }
  for i:=1 to l do
  begin
    q:= trunc(sqrt(a[i]));
    for j:=1 to i-1 do if (a[j] > 2) then begin
     if (a[j] > q) then break; { т.к. перебираем до sqrt(a[i])}
     if (a[i] mod a[j]=0)
       then begin
         a[i]:=-1;
         break;
       end;
    end;
  end;
  for i:=1 to l do 
    if a[i]>=n then writeln(a[i]);
end.
AllSuccess1.ru - каталог полезных курсов.
Tony Parker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
простые числа Koko Shanel' Помощь студентам 2 08.09.2010 01:13
Простые числа Verochka Помощь студентам 14 02.12.2008 20:30
Простые числа werser Помощь студентам 8 18.06.2008 07:24
простые числа Акашаев Нурлан Паскаль, Turbo Pascal, PascalABC.NET 2 05.12.2007 12:23