こんにちは、Mottyです。今回は配列の記事になります。
循環配列
循環配列はcyclicな配列のことを言います。
普通の配列であれば最後の要素から次の要素へアクセスしようとするとエラーが検出されますが、循環配列では最初の要素にシフトします。
循環配列の中の任意の番号から始まり、要素をすべて取り出す方法を考えるとします。この場合、もう1つ同じ配列をコピーしそれにアクセスする方法があります。
ただし以下のデメリットが考えられます。
・2倍のメモリを確保しなければならない
・実装コードが冗長になる
//funcfunctionwrite(array,start_num){array=array.concat(array);//自分の配列同士を結合させる//順次書き込みfor(letindex=start_num;index<array.length/2+start_num;index++){console.log(array[index]);}}//Mainvarmyarray=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];write(myarray,7);// myarrayを7番目から取り出す//output: 7,8,9,10,11,12,13,14,15,16,17,18,19,20,0,1,2,3,4,5,6
上記のデメリットを解消する良い方法はあるのでしょうか(語り風)。
剰余(mod)を使えばcyclicな配列のシフトが可能です。
//funcfunctionwrite(array,start_num){for(letindex=start_num;index<array.length+start_num;index++){console.log(array[index%array.length]);}}//Mainvarmyarray=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19];write(myarray,7);// myarrayを7番目から取り出す//output: 7,8,9,10,11,12,13,14,15,16,17,18,19,20,0,1,2,3,4,5,6
見かけはインデックスを配列の長さで割った余りの数にアクセスしていることになりますが、インデックスが配列の長さを超えた場合にはじめの要素にバックします。これにより配列に循環的な性質を持たせることが可能となります。
下記例ではクリックすると色が変わるボタンを実装しています。
html部分
<DOCTYPE!html><html><head><title>循環配列</title><linkrel="stylesheet"type="text/css"href="layout.css"><script type = "text/javascript"src = "script.js"></script></head><body><buttonid = "target"value ="button"onclick = "buttonclick()">ThisButton</button><divid = "area"></div></div></body></html>
Layout部分
#target{display:inline-block;text-decoration:none;background:red;color:white;font-size:20px;width:120px;height:120px;line-height:120px;border-radius:50%;text-align:center;overflow:hidden;transition:.4s;}
Script部分
varcolorlist=["red","orange","yellow","green","blue","purple","black"];varcolor_num=0;functionbuttonclick(){color_num+=1;document.getElementById("target").style.backgroundColor=colorlist[color_num%colorlist.length];}
仕掛けは、ボタンをクリックする度にカラー配列内に順次アクセスし、CSSに反映させているということしかやっていません。ロジックが配列数によらないので要素を追加・削除したい場合は配列内のプロパティを修正だけでOKです。
まとめ
実情はjavascriptの練習がてらという感じです。型に制限がないっていうのもなかなか慣れないものですね・・・。
参考URL
・循環バッファ
https://ufcpp.net/study/algorithm/col_circular.html
・循環配列を用いたキューの実装
https://qiita.com/maebaru/items/fb640c16733301f836f7
・wikipedia
https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%90%E3%83%83%E3%83%95%E3%82%A1
・CycularArray(英語)
https://www.geeksforgeeks.org/circular-array/