Примечание: Версия 2, ниже, использует Сито Эратосфена. Есть несколько ответов, которые помогли с тем, что я первоначально спросил. Я выбрал метод Sieve of Eratosthenes, реализовал его и изменил название вопроса и метки соответствующим образом. Спасибо всем, кто помог!
Введение
Я написал этот причудливый маленький метод, который генерирует массив int, содержащий простые числа, меньшие указанной верхней границы. Это работает очень хорошо, но у меня есть проблема.
Метод
private static int [] generatePrimes(int max) {
int [] temp = new int [max];
temp [0] = 2;
int index = 1;
int prime = 1;
boolean isPrime = false;
while((prime += 2) <= max) {
isPrime = true;
for(int i = 0; i < index; i++) {
if(prime % temp [i] == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
temp [index++] = prime;
}
}
int [] primes = new int [index];
while(--index >= 0) {
primes [index] = temp [index];
}
return primes;
}
Моя забота
Меня беспокоит то, что я создаю массив, который слишком велик для конечного числа элементов, которое будет возвращать метод. Проблема в том, что я не знаю, как правильно угадать число простых чисел меньше указанного числа.
Фокус
Так программа использует массивы. Это то, что я хочу улучшить.
- Я создаю временный массив, который
достаточно большой, чтобы вместить каждый номер
меньше лимита.
- Я генерирую простые числа, а
ведя подсчет, сколько у меня есть
генерируется.
- Я создаю новый массив, который является правильным
измерение, чтобы держать только премьер
число.
- Я копирую каждое простое число из
огромный массив к массиву
правильный размер.
- возвращаю массив правильный
измерение, которое содержит только простое
числа, которые я сгенерировал.
Вопросы
- Могу ли я скопировать весь кусок (сразу) из
temp[]
с ненулевым
элементы к primes[]
без необходимости перебирать
оба массива и скопировать элементы
один за другим?
- Существуют ли структуры данных, которые
вести себя как массив примитивов
которые могут расти при добавлении элементов,
вместо того, чтобы требовать измерения
на момент создания? Что
снижение производительности по сравнению с
используя массив примитивов?
Версия 2 (спасибо Джону Скиту ):
private static int [] generatePrimes(int max) {
int [] temp = new int [max];
temp [0] = 2;
int index = 1;
int prime = 1;
boolean isPrime = false;
while((prime += 2) <= max) {
isPrime = true;
for(int i = 0; i < index; i++) {
if(prime % temp [i] == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
temp [index++] = prime;
}
}
return Arrays.copyOfRange(temp, 0, index);
}
Версия 3 (благодаря Полу Томблину ), в котором используется Сито Эрастосфена :
private static int [] generatePrimes(int max) {
boolean[] isComposite = new boolean[max + 1];
for (int i = 2; i * i <= max; i++) {
if (!isComposite [i]) {
for (int j = i; i * j <= max; j++) {
isComposite [i*j] = true;
}
}
}
int numPrimes = 0;
for (int i = 2; i <= max; i++) {
if (!isComposite [i]) numPrimes++;
}
int [] primes = new int [numPrimes];
int index = 0;
for (int i = 2; i <= max; i++) {
if (!isComposite [i]) primes [index++] = i;
}
return primes;
}