Форум: Форум C++Разное
Новые темы: 00
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум C++

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Простые числа?
 
 автор: hell_riser   (16.01.2008 в 12:32)   письмо автору
 
 

Всем доброго времени суток.
Где-то на сайте вроде бы видел похожие темы, но к сожалению на даный момент нет времени сильно глубоко копать, если вас не затруднит помогите бедному студенту )).
В общем есть задача:
- Напишите на языке Си программу, определяющую, является ли введеное пользователем натуральное число простым ( Объясните пожалуйста алгоритм проверки числа на "простоту" ).

#include <stdio.h>
#include <conio.h>
int num, pr;
void main()
{
 puts("Введите натуральное число - ");
 scanf("%d", &num);
 if(num<0)
  printf("Число \"%d\" не натуральное", num);
 else
 {
  pr=num%2;/* Принимаем за делитель для проверки минимальное простое чило*/
  if(pr)
  printf("Число \"%d\" является простым.", num);
  else
  printf("Число \"%d\" не является простым.", num);
 }
 puts("Для закрытия нажмите любую клавишу");
 getch();
}

с одной стороны вроде бы как и работает (по крайней мере при малых значениях), а с другой стороны как-то слишком просто (((.

  Ответить  
 
 автор: Фитч   (17.01.2008 в 08:29)   письмо автору
 
   для: hell_riser   (16.01.2008 в 12:32)
 

Вы проверяете число на четность.
Вот такая проверка простое/составное:

if ( (num % 2) != 0 ) // если число нечетное, иначе оно составное
{
 for(int i = 3; i < num / 2; i++) 
 // имеет смысл искатьделители только среди чисел, меньших num/2
 {
  if ( (num % i) == 0 )
  {
   // число простое - найден делитель i
  }
 }
}

  Ответить  
 
 автор: alex19921992   (17.01.2008 в 10:36)   письмо автору
 
   для: Фитч   (17.01.2008 в 08:29)
 

Более того, имеет смысл искать делители только меньше корня квадратного из num!

  Ответить  
 
 автор: hell_riser   (17.01.2008 в 11:08)   письмо автору
 
   для: alex19921992   (17.01.2008 в 10:36)
 

А пример не могли бы привести.
Вообще-то преподаватель разрешила и просто тупо в цикле с шагом 1 прогнать поиск делителя, но для себя интересно просто разные варианты по сравнивать(единственный предмет который буду сам сдавать и интересен на 1 курсе).

  Ответить  
 
 автор: Фитч   (17.01.2008 в 13:11)   письмо автору
 
   для: hell_riser   (17.01.2008 в 11:08)
 

Вот, можете сравнить производительность:

#include <math.h>
#include <stdio.h>
#include <windows.h>

inline bool isSimple1(long num)
{
 if ( (num % 2) != 0)
 {
  for(int i = 0; i < (num / 2); i++)
  {
   if ( (num % i) == 0)
   {
    return false;
   }
  }
  return true;
 }
 return false;
}

inline bool isSimple2(long num)
{
 if ( (num % 2) != 0)
 {
  for(int i = 0; i < sqrt(num); i++)
  {
   if ( (num % i) == 0)
   {
    return false;
   }
  }
  return true;
 }
 return true;
}

int main()
{
 DWORD dwTime = GetTickCount();
 
 for(int i = 0; i < 200000000; i++)
 {
  isSimple1rand() / RAND_MAX * 2000000000 );
 }
 printf("Метод с делением пополам: %d мс\n"GetTickCount() - dwTime);
 
 dwTime = GetTickCount();
 for(int i = 0; i < 200000000; i++)
 {
  isSimple2rand() / RAND_MAX * 2000000000 );
 }
 printf("Метод с квадратным корнем: %d мс\n"GetTickCount() - dwTime);
 
 scanf("\n");
 return 0;
}

  Ответить  
 
 автор: alex19921992   (19.01.2008 в 08:28)   письмо автору
 
   для: Фитч   (17.01.2008 в 13:11)
 

Эээ, нет батенька не все так просто!

for(int i = 0; i < sqrt(num); i++)
{
}

зачем дофига раз считать квадратный корень???

лучше вот так:

int temp=sqrt(num);
for(int i = 0; i < temp; i++)
{
}


Корень быстрее. Ибо проверок меньше будет.

  Ответить  
 
 автор: Фитч   (19.01.2008 в 11:46)   письмо автору
 
   для: alex19921992   (19.01.2008 в 08:28)
 

Хех, понадеялся на автооптимизацию - а зря! Получается выигрыш примерно на 90-110 мс.
Кстати, что странно - у меня в 2 случаях из 3 побеждает вервый вариант с разницей в 200-300 мс, а вот в оставшемся случае - второй, причем с разницей почти в секунду. Интересно, почему?

  Ответить  
 
 автор: alex19921992   (20.01.2008 в 07:22)   письмо автору
 
   для: Фитч   (19.01.2008 в 11:46)
 

Хм..
я думаю, при малых числах, выигрывает первый вариант, где без корня,
так как проверок там не сильно больше, чем в варианте с корнем.
то есть цикл выполняется примерно одинаковое число раз при малых числах.
но во втором варианте мы еще считаем один раз корень! а это ресурсоемкая операция.

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

  Ответить  
 
 автор: hell_riser   (21.01.2008 в 17:07)   письмо автору
 
   для: alex19921992   (20.01.2008 в 07:22)
 

Всем спасибо, только после того как сдал контрольную с вариантом sqrt мне усложнили задачу, что бы не умничал ((
http://www.softtime.ru/cpp/read.php?id_forum=1&id_theme=676

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования