如何在 JavaScript 中實現蝴蝶洗牌演算法?
在 JavaScript 中,蝴蝶洗牌陣列是指一個數字陣列,其排序方式為:越靠近陣列中心,數字越小;越靠近陣列兩端,數字越大。最大的數字位於第一個索引位置。
蝴蝶洗牌陣列的另一種變體是:越靠近陣列中心,數字越大;越靠近陣列兩端,數字越小。在這種情況下,最小的數字位於第一個索引位置。
對於有數學背景的人來說,這與高斯分佈有些相似。
示例
假設我們有以下陣列:
const arr = [8,2,6,3,9,1,4,5,0,7];
如果我們對其應用蝴蝶洗牌演算法,輸出將為:
[9, 7, 5, 3, 1,0, 2, 4, 6, 8]
可以看到,最大和第二大的數字位於陣列的兩端,最小的數字位於陣列的中心。
另一種可能性是:
[0, 2, 4, 6, 8, 9, 7, 5, 3, 1]
我們的任務是編寫一個函式,該函式接收一個數字陣列和一個字串作為第二個引數,字串可以取兩個值中的任何一個:“asc” 或 “des”。
如果字串為“des”,則我們必須按升序到降序的順序對陣列進行洗牌。
如果字串為“asc”,則我們必須按降序到升序的順序對陣列進行洗牌。
方法
如果字串為“asc”,我們首先按升序對陣列進行排序,否則按降序排序。因此,假設函式被呼叫時帶了“asc”,那麼陣列現在將如下所示:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
然後我們將陣列分成兩個陣列,使相鄰元素分佈在不同的陣列中。我們將元素推入一個數組,同時將其移到另一個數組的開頭,這樣一來,一個數組就會被反轉,而無需我們手動進行反轉操作。
這樣形成的兩個陣列將如下所示:
[ 0, 2, 4, 6, 8 ] [ 9, 7, 5, 3, 1 ]
現在,最後一步是連線這兩個陣列,之後我們將得到所需的陣列。將所有這些程式碼放在一起,看起來就像這樣:
示例
const array = [8,2,6,3,9,1,4,5,0,7]; const butterflyShuffle = (array, order = 'asc') => { //creating a new copy of array so that we dont mutate the original array const arr = array.slice(); //sorting ascending or descending based on the argument arr.sort((a, b) => order === 'asc' ? a-b : b-a); const first = [], second = []; //this variable will later help in determining which array is to be reversed //and which one is to be concatenated to which //if length is even, it means that last element will go in second array //otherwise it will go in first array const isEven = arr.length % 2 === 0; for (let i = 0; i < arr.length; i++){ if(i % 2 === 0){ isEven ? first.push(arr[i]) : first.unshift(arr[i]); continue; }; isEven ? second.unshift(arr[i]) : second.push(arr[i]); }; return isEven ? second.concat(first) : first.concat(second); }; console.log(butterflyShuffle(array)); console.log(butterflyShuffle(array, 'des'));
輸出
控制檯中的輸出將為:
[ 9, 7, 5, 3, 1, 0, 2, 4, 6, 8 ] [ 0, 2, 4, 6, 8, 9, 7, 5, 3, 1 ]
廣告