Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8945

【Node.js】JavaScriptで組み合わせ,順列を列挙する (npmモジュールあり)

$
0
0

JSで組み合わせと順列を列挙する標準メソッドはない

Rubyだと

index.rb
array=[1,3,5];#組み合わせparray.combination(2).to_a# => [[1, 3], [1, 5], [3, 5]]#順列parray.permutation(2).to_a# => [[1, 3], [1, 5], [3, 1], [3, 5], [5, 1], [5, 3]]

こんな感じで簡単に組み合わせ、順列の列挙ができるのにJavaScriptだとこれがない。Mathオブジェクトのメソッドにあってもいい気がするんだけど。。。

とにかくこのままだとpaizaで組み合わせ、順列の問題が出てくるたびにrubyで一から書き直す羽目になるので、JavaScriptで順列と組み合わせを列挙するコードを考え、ついでにrubyのコードより分かりやすく記述できるnpmモジュールも作りました。

コード

これから載せるのは実際にモジュールを作る際に書いたコードなのでしっかり動くはずです。

組み合わせ

//0~n-1の数字をk個ずつの組み合わせで列挙する関数functionrec(n,k){if(k===0)return[[]];constresult=[];for(leti=0;i<n;i++){if(n-i-1<k-1)continue;rec(n-i-1,k-1).forEach((js)=>{result.push([i,...js.map((j)=>j+i+1)]);});}returnresult;}//rec関数を使って返ってきた配列をarrayのインデックス番号と見立てて配列の組み合わせを作るfunctioncom(array,num){constlast=rec(array.length,num);constresult=[];for(letite=0;ite<last.length;ite++){constanswer=[];for(letfin=0;fin<last[ite].length;fin++){answer.push(array[last[ite][fin]]);}result.push(answer);}returnresult;}

コード自体はそこまで長くないが、rec関数ではfor文をfor文で繰り返す回数が動的(語彙力)なので再帰関数を使うのがミソ。これに関しては「組み合わせ 列挙 javascript」でググれば上の方に出てくる記事(こんなのとか)にもあるので詳しくそちらを見ることをお勧めします。正直僕もあまり理解していません。

順列

//順列のコードは分からなかったので他サイト(後述)のほぼコピペconstper=(array,num)=>{constresult=[];if(array.length<num){return[];}if(num===1){for(leti=0;i<array.length;i++){result[i]=[array[i]];}}else{for(leti=0;i<array.length;i++){constparts=array.slice(0);parts.splice(i,1)[0];constrow=per(parts,num-1);for(letj=0;j<row.length;j++){result.push([array[i]].concat(row[j]));}}}returnresult;};

「組み合わせのrec関数を少し変えれば順列も作れるだろ」と鷹を括っていたものの、実際考えてみると全く思い浮かばず、結局他サイトのコードを少し変えただけという情けない結果に終わりました。このサイトの組み合わせのコードを使えば上のrec関数のくだりも必要ないのですが、流石にそれはあかん。ちなみにこの関数も再帰してますね。

作ったnpmモジュール

このコードを使ってモジュールを作ったので、開発の際に組み合わせ、順列の列挙がしたいという方は是非使ってみてください。

percom

permutation(順列)の"per"とcombination(組み合わせ)の"com"をくっつけた安直な命名。
npmページ
GitHub

環境設定は簡単。

こうして

$ npm i percom

こうするだけ

constpercom=require('percom');

組み合わせ

組み合わせを列挙したければ

constarray=[1,2,3]//もちろん文字列の配列でも可constcombinations=percom.com(array,2);//combinations = [ [ "A", "B" ], [ "A, "C ], [ "B", "C" ] ]

順列

順列を列挙したければ

constarray=[1,2,3]//もちろん文字列の配列でも可constpermutations=percom.per(array,2);//permutations = [ [ 'A', 'B' ], [ 'A', 'C' ], [ 'B', 'A' ], [ 'B', 'C' ], [ 'C', 'A' ], [ 'C', 'B' ] ]

percom.com()もpercom.per()も第一引数に対象の配列、第二引数に列挙する組み合わせの要素数を入力すれば上手くいきます。


一から自分で作ったわけではありませんが割と苦労して作ったモジュールなので是非使ってください。ちなみにpaizaとかAtcoderではどのみちモジュールは使えないのでこのコードをコピペして使ってください。

Twitter


Viewing all articles
Browse latest Browse all 8945

Trending Articles