Javascript 编写一个JS函数来查找具有给定步长值的第一个素数对
**这是Codewars提出的问题 素数的间隔不是规则的。例如,从2到3,步骤为1。从3到5,步骤是2。从7点到11点是4点。在2到50之间,我们有以下两对2步素数: 3,5-5,7-11,13-17,19-29,31-41,43 我们将编写一个带有参数的函数步骤: g(整数>=2),表示我们要查找的步骤 m(整数>=2),它给出搜索的开始(包括m) n(整数>=m)表示搜索结束(包括n) 在上面的示例中,步骤(2,2,50)将返回[3,5],这是2和50之间具有2步的第一对 所以这个函数应该返回两个素数的第一对,如果这些g步素数存在,则在极限m,n之间间隔g步,否则为nil或null或None或Nothing(取决于语言) 示例: 步骤(2,5,7)->[5,7]或(5,7)或{5,7} 步骤(2、5、5)->nil或null 步骤(4130200)->[163167]或(163167)或{163167} 这是我的解决方案——通过测试的时间太长了——我怎样才能使它更有效Javascript 编写一个JS函数来查找具有给定步长值的第一个素数对,javascript,Javascript,**这是Codewars提出的问题 素数的间隔不是规则的。例如,从2到3,步骤为1。从3到5,步骤是2。从7点到11点是4点。在2到50之间,我们有以下两对2步素数: 3,5-5,7-11,13-17,19-29,31-41,43 我们将编写一个带有参数的函数步骤: g(整数>=2),表示我们要查找的步骤 m(整数>=2),它给出搜索的开始(包括m) n(整数>=m)表示搜索结束(包括n) 在上面的示例中,步骤(2,2,50)将返回[3,5],这是2和50之间具有2步的第一对 所以这个函数应该返
function step(g, m, n) {
var arr = [];
function isPrime(num){
for (var k=2; k<num; k++){
if(num%k ===0){
return false;
}
}return true;
}
for (var i= m; i < n; i++){
if(isPrime(i)=== true){
arr.push(i);
}
}
var endArr=[];
for(var l=0;l<arr.length;l++)
for(var p=1;p<arr.length;p++){
if(arr[l]-arr[l-p]=== g){
endArr.push(arr[l])
endArr.push(arr[l]-g)
}
}
return endArr.slice(0,2).sort(function(a,b){
return a-b;
})
}
功能步骤(g、m、n){
var-arr=[];
函数isPrime(num){
对于(var k=2;k,这里有几个有趣的点
首先,您的isPrime
实现效率低下。最快的方法是使用预缓存集(很容易准备一个),但即使没有预缓存集,您也只能通过将其除以素数来检查候选集,当下一个素数除数大于sqrt(cand)
时退出
例如,如果您已经知道2、3、5和7是素数,您可以通过将11
除以3(如5>Math.sqrt(11)
)来检测11
是素数哦,我有没有提到过您永远不会检查大于2的偶数
第二,您的实现尝试查找给定范围内的所有素数,然后尝试查找满足“差分条件”的所有素数。但是请记住,您的任务实际上是查找具有给定步骤的两个素数的第一对
记住这一点,为什么不检查一个数字(n
),如果它是素数,尝试检查n+g
的素数?您可以缓存该检查的结果,以便以后跳过它
这里有一种可能的方法:
function findPrimesByStep(g, m, n) {
let primes = new Set([2]);
function isPrimeNumber(candidate) {
if (primes.has(candidate)) {
return true;
}
let lim = Math.sqrt(candidate);
for (let prime of primes) {
if (prime > lim) {
break;
}
if (candidate % prime === 0) {
return false;
}
}
primes.add(candidate);
return true;
}
n = n - g;
for (let i = 3; i <= n; i += 2) {
let isPrime = isPrimeNumber(i);
if (isPrime && i >= m && isPrimeNumber(i + g)) {
return [i, i + g];
}
}
return null;
}
函数findpromesbystep(g,m,n){
设素数=新集([2]);
函数isPrimeNumber(候选){
if(素数has(候选者)){
返回true;
}
设lim=Math.sqrt(候选者);
for(设素数的素数){
if(prime>lim){
打破
}
如果(候选%prime==0){
返回false;
}
}
素数。添加(候选);
返回true;
}
n=n-g;
对于(设i=3;i=m&&isPrimeNumber(i+g)){
返回[i,i+g];
}
}
返回null;
}
这是不完整且未优化的(它不检查琐碎的情况,它跳过2,不需要大于sqrt(n)
)的素数),但显示了它是如何实现的。您的isPrime
函数很简单。您正在测试从2到k的每个数字。首先,唯一的偶数素数是2,因此测试4、6、8等是不必要的。您不必在num
之前测试每个数字。相反,您可以在sqrt(num)之后停止
。然后已经证明,所有大于2的素数的形式都是6n-1或6n+1
。即6*1-1=5
,6*1+1=7
,6*2-1=11
,6*2+1=13
,等等。(不是所有的素数,但不是这种形式的数都不是素数).因为你看到的数字很小,你可以使用一个预先计算好的所有素数的表格,比如埃拉托什尼。