配列について、その要素を並べ替えて得られる配列を重複することなく全て得たいです。
要素数が5つなら5!で120通り、nであればn!通りの配列をすべて得たい、といった具合です。
自分で組んでみたところ、再帰呼び出しを多用しているせいか要素を8つにした時点でFirefoxだと「このページのスクリプトは処理に時間がかかっているか応答しなくなっています。…」、IEでも似たような警告文が表示されてしまいます。
コードは以下に示すとおりです。
そこでお聞きしたいのは、
1.「処理に時間が~云々」などの表示をさせずに処理を
続けさせるにはどのように書いたらいいか
2.もっと短くスマートなコードで全走査できないか
の2つです。
1.についてはユーザサイドでなく開発者サイドで、かつalertを使う以外の方法で、警告文を出させないで処理を続けさせるためにはコードをどのようにしたらよいでしょうか。
2.に関しては、私が書いたコードは正直わかりにくいと思いますので、もっとシンプルに全走査できるアルゴリズムがあったら教えてほしいです。
どうかよろしくお願いします。
<html>
<body>
<script type="text/javascript">
<!--
//Arrayオブジェクトに自身をコピーした配列を返すclone()メソッド追加
Array.prototype.clone = function(){
// 自分自身が配列かをチェック
if(this[0].constructor == Array ){
var ar, n;
//新しい配列を用意する
ar = new Array(this.length);
for(var n=0;n<ar.length;n++){
//再起呼び出しで配列の中身をコピー
ar[n] = this[n].clone();
}
//作成した配列を返す
return ar;
}
return Array.apply(null,this);
}
//★要素を並べ替える前の配列の宣言
var ar = new Array("1","2","3","4","5","6","7","8");
//並べ替え後の配列を格納する配列宣言
var arranged_ar = new Array();
function arArrange(){
//引数は(呼び出した節の、並び替える前の配列内での順番,すでに取り出した節の配列,兄弟の配列)
function createBranch(parentCounter,parentNodes,sameDepthBranches){
var branches = new Array(); //呼び出した節の子ノード格納用の配列宣言
branches = sameDepthBranches.clone(); //呼び出した節の兄弟をコピー
branches.splice(parentCounter,1) //呼び出した節を除いて子ノードの配列作成完了
var pushed_ar = new Array(); //この節以前に登場した節を格納する(最終的に並べ替え終わった配列になる)配列宣言
pushed_ar = parentNodes.clone(); //呼び出し元のpushed_arをコピー
for(var i=0;i<branches.length;i++){
pushed_ar.push(branches[i]); //pushed_arに子ノードを1つ追加
//走査が葉ノードに達したときの処理
if(pushed_ar.length == ar.length){
var length = arranged_ar.length;
arranged_ar[length] = new Array();
for(var j=0;j<pushed_ar.length;j++){
arranged_ar[length].push(pushed_ar[j]); //arranged_arに並び替え後の配列を格納
}
//走査がまだ葉ノードに達していない場合の処理
}else{
createBranch(i,pushed_ar,branches); //自身を再帰呼び出しすることで葉ノードに達するまでループ
}
//子ノード以下の走査が終わった場合の処理
pushed_ar.splice(pushed_ar.length-1,1); //追加した子ノードを削除して次の子ノード追加へ
}
return;
}
//↑で宣言したcreateBranch関数の呼び出し
for(i=0;i<ar.length;i++){
var tempAr = new Array();
tempAr.push(ar[i]);
createBranch(i,tempAr,ar);
}
//結果をresultに格納
var result = "";
for(var i=0;i<arranged_ar.length;i++){
result += i+1 + ": ";
for(var j=0;j<arranged_ar[i].length;j++){
result += arranged_ar[i][j] + ",";
}
result += "<br>";
}
//結果を画面に表示
document.getElementById("result").innerHTML = result;
return;
}
-->
</script>
<input type="button" value="全並べ替えパターン走査" onclick="arArrange();">
<p id="result">ここに結果表示</p>
</body>
</html>
お礼
実際に試したところ問題なく機能いたしました。 大変勉強になりました。ありがとうございます。