![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
n199a |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.11.2011 Репутация: нет Всего: нет |
Принцип действия решета:
Другая задача, которую решили математики Древней Греции — нахождение всех простых чисел в интервале от 1 до заданного числа N. Самым быстрым и поныне считается алгоритм Эратосфена (275-195 гг. до н.э.). Существует предание, что Эратосфен выписал в ряд на папи- русе все натуральные числа и затем прокалывал каждое второе (то есть делящееся на 2), потом — каждое третье, и т.д. В конце этой процедуры остаются «непроколотыми» только простые числа, которые делятся только на себя и на 1. Вместо папируса мы будем использовать массив A, в котором элемент A[i] для всех i от 1 до N принимает два возможных значения: 1, число «не проколото» и является кандидатом на простые; 0, число «проколото» и больше не рассматривается. Вопрос: Зачем прокалывать каждое второе я понял - если их проколоть, останутся нечетные (делятся на 1 и на себя). А вот зачем прокалывать потом каждое 3-е, потом каждое 4-ое? 1 2 3 4 5 6 7 8 9 10 11 12 x x x x x x //каждое второе x x x x //кажое 3-е x x x //каждое 4-ое
После ввода числа аварийно завершается программа. Непонятные моменты: for (i = 1; i <= N; i++) A[i] = 1; 1) Вводили указатель *A, тут получился уже массив A[i] 2) В массиве A[i] i-ый элемент будет равен единице. Что-то не так ![]() Это сообщение отредактировал(а) n199a - 7.7.2013, 20:43 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
где? Его не вводили, а определяли.
когда ты выделил память с помощью new ты получил динамический массив на N+1 элемент кстати, в языке Си массивы индексируются с 0. |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Вот нечётные не обязательно делятся только на 1 и на себя. Рассмотрите такие числа как 9, 15, 21, 25 и т.д. Как раз, чтобы исключить числа, которые делятся на 3,4 etc. Ну как бы это сказать... Если путать "равно" и "двойное равно"... Более того, не нужно проверять на NULL значение, возвращаемое от new (в случае нехватки памяти будет брошено исключение). А что тут непонятного... Инициализируется массив единицами (как бы изначально считаем, что все числа - простые, а потом исключаем составные путём A[i] = 0). Добавлено через 1 минуту и 52 секунды Тут просто значение индекса и значение числа - одно и то же (это разумно для этой задачи), 0-ой индекс не используется, а памяти выделяется на 1 элемент больше ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
feodorv, я заметил.
![]() |
|||
|
||||
n199a |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 129 Регистрация: 17.11.2011 Репутация: нет Всего: нет |
Что означает - брошено исключение? В учебнике пишут, что, может затереться любой участок памяти и произойдёт непредвиденный сбой. Если так прокалывать, то проколются ВСЕ числа, смотри: 1 2 3 4 5 6 7 8 9 10 11 12 x x x x x x //каждое второе x x x x //кажое 3-е x x x //каждое 4-ое x x x x x x x x x x Что тут исключается? В итоге то полностью каждое число проколется. Что останется? Добавлено @ 12:10 Не понял намек. Я про то, что, после ввода числа вылазит ошибка (отправить отчет и не отправлять отчет об ошибке). Т.е. программа нерабочая. Я в этом смысле. Что тут не так, может у вас нормально будет? Это сообщение отредактировал(а) n199a - 8.7.2013, 12:12 |
|||
|
||||
SenkraD |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 3.2.2006 Где: Украина::Киев Репутация: нет Всего: 23 |
Это сообщение отредактировал(а) SenkraD - 8.7.2013, 13:02 |
|||
|
||||
feodorv |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ну всё же кристально ясно. = это присваивание, == а это сравнение. И что делаете Вы? Вы присваиваете (не сравниваете!!!) указателю A значение NULL (то есть 0). Получается, что Ваш код эквивалентен такому
Поскольку 0 - это всегда "ложь", то программа продолжает работать дальше, но уже с A, равному NULL. И что дальше? А дальше То есть попытка присвоения значения по нулевому указателю. А это даёт то самое
Правильно так:
Двойное равно, однако ![]()
Если указатель имеет мусорное значение (какое-то произвольное, от балды), то да. Если как у нас - вполне определённый 0 (NULL), то однозначно произойдёт сбой (ничего затираться не будет). В этом великая сила нулевого указателя (ну и ряда других специальных значений). Вам сюда. Выкиньте вообще эту строчку с проверкой на NULL.
Ну Вы тогда не поняли смысл решета. Не каждое ![]() Где здесь каждое? Для 40:
PS Пардон, что на "вы", не заметил, что можно на "ты". Добавлено через 31 секунду SenkraD, ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||||
|
|||||||||||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Не))) Нужно пройтись по всем кратным k: 2k, 3k, 4k ... до N (по мере возможности))) Так исключаются составные числа, в разложение которых входит k. Само k не берём в рассмотрение, так как оно как раз простое (кроме единицы, которая не входит в цикл, так как отсчёт начинается от 2, но которую, по большому счёту тоже стоит исключить из списка простых чисел) из-за проверки (а если A[k] равно 0, то k - составное, и смысла в просеивании нет - уже всё просеяно до нас)))
Это да ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
feodorv, допустим в какой-то момент k = 7 Зачем проходицца по 2*7, 3*7, 4*7 ? Прежде чем к стало 7, оно было 2, 3, 4 и т.д. То есть, числа кратные 2,3,4,5,6 уже и так зачеркнуты. Первое число которое может быть не зачеркнутым это 7*7 Следовательно можно начинать сразу с 7*7 Разве нет? Добавлено @ 01:37 Щас поздно уже, мозги не варят, завтра проверю. Это сообщение отредактировал(а) volatile - 9.7.2013, 01:40 |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ха, а ведь весьма даже может быть!!! Мда, век живи, век учись ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Ну собственно, проверять и нет особой необходимости. В википедии алгоритм так и приведен :
Решето Эратосфена Кстати, для n199a, там есть гиф-анимашка, поясняющая работу, возможно поможет вам понять. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |