JavaScript特有の方法は、バイナリ中の1の個数のsplitを計算する方法です.
3093 ワード
コードは以下の通りです
残念ながら、次の2つの方法の効率をテストしました.正規のsplitを利用する方法は効率が低く、時間はfor循環法の2.5倍ぐらいです.
function f(n){returnn n.toString(2).split(/0*/).length;function g(n){var n=n=n.toString(2);var count=0;var tmp=";for(var i=0;i=0;i<n.length;n+littttttn+i+i+i+++++++++++++++harittttttttttttttttttlit""""""""""""""""""""""""""""""""""""""""""""""""+f(12345789987654321)+「<bragt;」)var now=Date.now();for(var j=0;j<10000;j+)f(12345789987654321)document.write(「splitメソッドにかかる時間(10000ステップ)」+(Dat.now()+「<bragt;」)document.write(「for方法計算結果:」+g(12345789987654321)+「<bragt;」)now=Date.now();for(var k=0;k<10000;k+)g(12345789987654321)document.write(「for循環方法にかかる時間(10000ステップ)」+(Dat.now)+「<bragt;」);
[Ctrl+A全選注:外部Jsを導入するにはリフレッシュが必要です.]
元のコードの中に二つのエラーがあることが分かりました.
一つは、IEの下で、文字列は、指定された位置の値に対して配列の下でアクセスできず、charAt(index)の方法しか採用できない.
二つはChromeとOperaで、split(\0*\)の方式で算出された1の個数は、場合によっては1より多くなります.
例えば、12のバイナリ値は1100で、split(\0*\)を用いて生成される配列は[1,1,]です.つまり、バイナリ値が1で終わらない場合、最後に1つの空配列項目が生成される(IEとFirefoxにはこの問題はない).
考えてみると、正則で1の個数を計算する必要はありません.1をスプリットメソッドのパラメータとして、1をセパレータとして、分割した配列の長さは1の個数に1を加算します.
function f(n){returnn n.toString(2).split("1").length-1;}function g(n){var m=n.toString(2);var count=0;for(var i=0;1234;m.length;i+i+){cmhard====""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""String(2)+「<bragt;<bragt;」);document.write(「for方法計算結果:」+g(12345789987654321)+「<bragt;」)var now=new Date();for(var k=0;k<10000;k+)g(12345789987654321)document.write(「for循環方法にかかる時間(10000ステップ)」+(new Date)+「<bragt;」);document.write(「split方法計算結果:」+f(12345789987654321)+「<bragt;」)now=new Date();for(var j=0;j<10000;j+)f(12345789987654321)document.write(「splitメソッドにかかる時間(10000歩):」+(new Date()+「<bragt;」)
[Ctrl+A全選注:外部Jsを導入するにはリフレッシュが必要です.]
function g(n){
var n = n.toString(2);
var count = 0;
for(var i=0;i{
if(n[i] == "1")
count++;
}
return count;
}
このように書くのは面倒臭いと思いますが、jsのsplit方法で1の個数を計算できるかどうかと思いました.splitのパラメータは正則\0*、文字列の1を分離します.コードは以下の通りです
function f(n){
return n.toString(2).split(/0*/).length;
}
コードはとてもシンプルに見えます.残念ながら、次の2つの方法の効率をテストしました.正規のsplitを利用する方法は効率が低く、時間はfor循環法の2.5倍ぐらいです.
function f(n){returnn n.toString(2).split(/0*/).length;function g(n){var n=n=n.toString(2);var count=0;var tmp=";for(var i=0;i=0;i<n.length;n+littttttn+i+i+i+++++++++++++++harittttttttttttttttttlit""""""""""""""""""""""""""""""""""""""""""""""""+f(12345789987654321)+「<bragt;」)var now=Date.now();for(var j=0;j<10000;j+)f(12345789987654321)document.write(「splitメソッドにかかる時間(10000ステップ)」+(Dat.now()+「<bragt;」)document.write(「for方法計算結果:」+g(12345789987654321)+「<bragt;」)now=Date.now();for(var k=0;k<10000;k+)g(12345789987654321)document.write(「for循環方法にかかる時間(10000ステップ)」+(Dat.now)+「<bragt;」);
[Ctrl+A全選注:外部Jsを導入するにはリフレッシュが必要です.]
元のコードの中に二つのエラーがあることが分かりました.
一つは、IEの下で、文字列は、指定された位置の値に対して配列の下でアクセスできず、charAt(index)の方法しか採用できない.
二つはChromeとOperaで、split(\0*\)の方式で算出された1の個数は、場合によっては1より多くなります.
例えば、12のバイナリ値は1100で、split(\0*\)を用いて生成される配列は[1,1,]です.つまり、バイナリ値が1で終わらない場合、最後に1つの空配列項目が生成される(IEとFirefoxにはこの問題はない).
考えてみると、正則で1の個数を計算する必要はありません.1をスプリットメソッドのパラメータとして、1をセパレータとして、分割した配列の長さは1の個数に1を加算します.
function f(n){
return n.toString(2).split("1").length �C 1;
}
このように正則の方法を採用しなくても、各主流のブラウザに対応しています.そして、その効率はforエルゴードの方法を使用するよりも低いです.function f(n){returnn n.toString(2).split("1").length-1;}function g(n){var m=n.toString(2);var count=0;for(var i=0;1234;m.length;i+i+){cmhard====""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""String(2)+「<bragt;<bragt;」);document.write(「for方法計算結果:」+g(12345789987654321)+「<bragt;」)var now=new Date();for(var k=0;k<10000;k+)g(12345789987654321)document.write(「for循環方法にかかる時間(10000ステップ)」+(new Date)+「<bragt;」);document.write(「split方法計算結果:」+f(12345789987654321)+「<bragt;」)now=new Date();for(var j=0;j<10000;j+)f(12345789987654321)document.write(「splitメソッドにかかる時間(10000歩):」+(new Date()+「<bragt;」)
[Ctrl+A全選注:外部Jsを導入するにはリフレッシュが必要です.]