Моя контрольная панель не работает. Я думаю, что есть более простые способы сделать эту задачу, но мне нужна функциональность:
Для заданного числа p:
1) Заполните массив numArray цифрами от 2 до p
Я достиг этого:
for (var i=2; i<(p + 1); i++) {
numArray.push(i);
};
2) Пока numArray не пуст:
добавьте первое число "prime" в numArray к массиву primeArray
сплайсинг каждого кратного штриха из numArray
Мой код не использует цикл while, потому что я не уверен, как использовать его для итерации по массиву, но цикл for тоже не работает?
МОЖЕТ ЛЮДИ ПРОСТО ОТВЕТИТЬ С ПРЕДЛОЖЕНИЯМИ, НЕ ПОЛНЫМИ ИСПЫТАНИЯМИ. Определенно, пожалуйста, не пишите полный код, который находит простые числа. Мне больше интересно узнать, как я могу перебирать массив, который я продолжаю нарезать в зависимости от элементов массива, и любые другие указатели о том, как структурировать мой код.
Также я смущен, почему
(numArray[k] % prime == 0)
кажется, пропуская числа?
function checkIfPrime(p) {
numArray = [];
primeArray = [];
for (var i = 2; i < (p + 1); i++) {
numArray.push(i);
};
for (var j = 0; j < numArray.length; j++) {
if (primeArray.indexOf(numArray[j]) === -1) { //if numArray of j is not already in primeArray
var prime = numArray[j];
console.log(prime + " is not in numArray")
primeArray.push(prime);
console.log(primeArray);
numArray.splice(j, 1);
console.log(numArray);
for (var k = 0; k < numArray.length; k++) {
if (numArray[k] % prime == 0) {
numArray.splice(k, 1);
};
}
}
};
}
p = 5;
console.log(checkIfPrime(p));
Поскольку вас больше интересуют предложения, чем рабочий код, давайте начнем с альтернатив.
Проблема заключается в том, что когда вы соединяете элемент из массива, он меняет свою длину. Ничего нового в этом нет, но проблема в том, что вы повторяете один и тот же массив.
Поэтому для заданного массива [2, 3, 4, 5]
, если j
равно 0, prime
2
. Таким образом, вы удаляете 2
и 4
. Таким образом, новая длина равна 2. Проблема состоит в том, что остальные элементы будут сдвинуты. Таким образом, это будет выглядеть как [3, 5]
.
Теперь на итерации j
будет равно 1
. Так оно начнется с 5
и пропустит 5.
Альтернатива:
Вместо удаления элементов присвойте им значение по умолчанию, которое будет пропущено по умолчанию. Таким образом, ваш индекс останется верным, и ваша логика будет простой.
function checkIfPrime(p) {
var numArray = [];
var primeArray = [];
for (var i = 2; i < (p + 1); i++) {
numArray.push(i);
};
for (var j = 0; j < numArray.length; j++) {
if (numArray[j] !== 0 && primeArray.indexOf(numArray[j]) === -1) { //if numArray of j is not already in primeArray
var prime = numArray[j];
primeArray.push(prime);
for (var k = 0; k < numArray.length; k++) {
if (numArray[k] % prime == 0) {
numArray[k] = 0;
};
}
}
};
console.log(primeArray)
}
p = 5;
console.log(checkIfPrime(p));
сплайсинг каждого кратного штриха из numArray
Самый простой способ - использовать Array.filter
. Если вы манипулируете массивом при выполнении цикла, это усложнит логику. Кроме того, объект должен быть неизменным. Таким образом, вы можете перебрать массив и создать массив temp с необходимыми значениями и заменить значение.
Это можно сделать с помощью array.filter
или даже с помощью for
.
numArray = numarray.filter(function(num){
return num % prime !== 0;
})
Предполагая, что numArray
будет иметь возможные простые числа, мы можем попытаться минимизировать очевидные не-кандидаты.
var numArray = [2, 3];
for (var i = 8; i<=p; i++) {
if(i % 2 !== 0 || i % 3 !== 0) {
numArray.push(i)
}
}
Кроме того, поскольку простые числа являются фиксированными, мы можем взять длину и предварительно вычислить список простых чисел. Если пользователь вводит большее число, вам просто нужно вычислить числа от предела до нового предела. Таким образом, вы сохраняете некоторое время обработки:
var numArray = [2, 3];
function computePrimes(limit) {
var init = numArray[numArray.length - 1] || 0;
for (var i = init; i<= limit; i++) {
if(isPrime) {
numArray.push(i);
}
}
}
function isPrime(num) {
for (var i = 3; i< num; i++) {
if(num % i === 0)
return true;
}
else false;
}
computePrimes(100);
function getPrimeNumbers(num) {
if(num > numArray[numArray.length - 1]) {
computePrimes(num);
}
// ... Your computation logic
}
Как сказал Майк, в целом плохая идея использовать for-loop для итерации по массиву при его изменении.
Я вижу два пути:
Управляйте своими итерационными переменными вручную и убедитесь, что они увеличиваются только тогда, когда это необходимо.
Или используйте метод фильтра массива. Вот базовый пример, чтобы вы начали:
[1,2,3].filter(function(x){return x != 2})
// Will return [1,2]
Имейте в виду, что это вернет новый массив с отфильтрованными значениями, поэтому вам придется его успокоить, выполняя что-то вроде numArray = numArray.filter(...)
splice
не влияли на индексирование того, чего вы еще не достигли, либо сделайте вдвойне тройную или четырехкратную уверенность в том, что в любое время вы пишетеnumArray.
а затем имя функции, вы обязательно обновите свою итерационную переменную по мере необходимости .