[英]JavaScript loop is too slow
我正在處理關於代碼戰的任務,但無法理解如何讓這個 function 對大數 <= 200000000000000 工作得更快。function 的目標非常簡單 - 我只需要計算二進制表示中出現的所有“1”在“左”和“右”之間(包括兩者)。
function countOnes(left, right) {
var sum=0;
for (var i=left; i<=right; i++){
var h=i.toString(2);
var len=h.length;
for (var j=0; j<len; j++){
if (h[j]==1){sum++;}
}
}
return sum;
}
提前致謝
由於按位運算符限制為 32 位(請參閱備注),此解決方案將此限制推至2**53 -1
,這是 JS Number.MAX_SAFE_INTEGER的值
請參閱https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
const p32 = 2**32
function countOnes_John_MJojo(left, right )
{
let sum = 0
for (let V=left; V<=right; V++)
{
for (let N=V;N; N&=N-1) sum++
for (let N=Math.trunc(V/p32);N; N&=N-1) sum++
}
return sum
}
/- 歷史: -\
\--------------/
使用按位運算符要快一點:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
-> 邏輯與
-> 邏輯右移
function countOnesBin( left, right )
{
let sum = 0
for (let N=left; N<=right; N++)
{
let Bin = N
for(let x = N.toString(2).length;x--;)
{
if ( Bin & 1 ) sum++
Bin = Bin >>1
}
}
return sum
}
正如@CodeBling建議的那樣,這可能會更好!
function countOnes_CodeBling (left, right)
{
let sum = 0
for (let N=left; N<=right; N++)
{
for(let Bin = N; Bin > 0; Bin = Bin >> 1)
{ if ( Bin & 1 ) sum++ }
}
return sum
}
這個是最好的:不知道有沒有可能:感謝@John
function countOnes_John (left, right)
{
let sum = 0
for (let V=left; V<=right; V++)
{
for (let N=V;N; N&=N-1) sum++
}
return sum
}
您可以使用拆分 function 並將塊的數量減去一加到您的總和中來避免第二次迭代:
function countOnes(left, right) {
var sum=0;
for (var i=left; i<=right; i++){
var h=i.toString(2);
sum += h.split('1').length -1;
}
return sum;
}
它仍然會很慢,但比您的原始代碼快得多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.