TypeScript調(diào)整數(shù)組元素順序算法
前言
有一個(gè)整數(shù)數(shù)組,我們想按照特定規(guī)則對(duì)數(shù)組中的元素進(jìn)行排序,比如:數(shù)組中的所有奇數(shù)位于數(shù)組的前半部分。
本文將帶大家實(shí)現(xiàn)這個(gè)算法,歡迎各位感興趣的開(kāi)發(fā)者閱讀本文。
實(shí)現(xiàn)思路
我們通過(guò)一個(gè)實(shí)例來(lái)分析下:假設(shè)有這樣一個(gè)數(shù)組:[2, 4, 5, 6, 7, 8, 9, 11],將奇數(shù)移動(dòng)到最前面后,就是:[11, 9, 5, 7, 6, 8, 4, 2]。
通過(guò)觀察后,我們發(fā)現(xiàn)在掃描這個(gè)數(shù)組的時(shí)候,如果發(fā)現(xiàn)有偶數(shù)出現(xiàn)在奇數(shù)的前面, 就交換他們的順序,交換之后就符合要求了。
因此,我們可以維護(hù)兩個(gè)指針:
- 第一個(gè)指針初始化時(shí)指向數(shù)組的第一個(gè)數(shù)字,它只向后移動(dòng);
- 第二個(gè)指針初始化時(shí)指向數(shù)組的最后一個(gè)數(shù)字,它只向前移動(dòng);
在兩個(gè)指針相遇之前,第一個(gè)指針總是位于第二個(gè)指針的前面。如果第一個(gè)指針指向的數(shù)字是偶數(shù),并且第二個(gè)指針指向的數(shù)字是奇數(shù),則交換這兩個(gè)數(shù)字。
接下來(lái),我們來(lái)通過(guò)圖來(lái)描述下上述例子交換指針的過(guò)程,如下所示:
- 第一個(gè)指針永遠(yuǎn)指向偶數(shù),如果不為偶數(shù)就向后移動(dòng);
- 第二個(gè)指針永遠(yuǎn)指向奇數(shù),如果不為奇數(shù)就向前移動(dòng);
- 當(dāng)兩個(gè)指針各自指向的數(shù)都符合條件時(shí),就交換兩個(gè)元素的位置;
- 交換完成后,重復(fù)上述步驟,直至兩個(gè)指針相遇或者第一個(gè)指針位于第二個(gè)指針之后則代表問(wèn)題已得到解決。
實(shí)現(xiàn)代碼
有了思路之后,我們來(lái)看下實(shí)現(xiàn)代碼,如下所示:
export class AdjustArrayOrder { // 指向數(shù)組元素的兩個(gè)指針:一個(gè)指向數(shù)組頭部、一個(gè)指向數(shù)組尾部 private begin = 0; private end = 0; // 調(diào)整數(shù)組中奇數(shù)與偶數(shù)元素的位置:奇數(shù)位于偶數(shù)前面 reorderOddEven(arr: Array<number>): void { this.end = arr.length - 1; while (this.begin < this.end) { // 向后移動(dòng)begin(轉(zhuǎn)成二進(jìn)制跟1做與運(yùn)算,運(yùn)算結(jié)果為0就表示為偶數(shù)),直至其指向偶數(shù) while (this.begin < this.end && (arr[this.begin] & 0x1) !== 0) { this.begin++; } // 向前移動(dòng)end(轉(zhuǎn)成二進(jìn)制跟1做與運(yùn)算,運(yùn)算結(jié)果為1就表示為奇數(shù)),直至其指向奇數(shù) while (this.begin < this.end && (arr[this.end] & 0x1) === 0) { this.end--; } // begin指向了偶數(shù),end指向了奇數(shù) if (this.begin < this.end) { // 交換兩個(gè)元素的順序 [arr[this.begin], arr[this.end]] = [arr[this.end], arr[this.begin]]; } } // 重置指針位置 this.begin = 0; this.end = 0; } }
代碼的可擴(kuò)展性
如果數(shù)組中的元素不按照奇前偶后排列,我們需要將其按照大小進(jìn)行劃分,所有負(fù)數(shù)都排在非負(fù)數(shù)的前面,應(yīng)該怎么做?
聰明的開(kāi)發(fā)者可能已經(jīng)想到了方案:雙指針的思路還是不變,我們只需修改內(nèi)層while循環(huán)的的判斷條件即可。
這樣回答沒(méi)有問(wèn)題,確實(shí)解決了這個(gè)問(wèn)題,那么如果再改改題目,我們需要把數(shù)組中的元素分為兩部分,能被3整除的數(shù)都在不能被3整除的數(shù)前面,應(yīng)該怎么做?
經(jīng)過(guò)思考后,我們發(fā)現(xiàn)這個(gè)問(wèn)題無(wú)論再怎么改變都有一個(gè)共同的部分:雙指針的邏輯永遠(yuǎn)不會(huì)變。變化的只是判斷條件,那么我們就可以把變化的部分提取成函數(shù),當(dāng)作參數(shù)讓調(diào)用者傳進(jìn)來(lái),這樣就完美的解決了這個(gè)問(wèn)題,也正是我們所提及的代碼的可擴(kuò)展性。
最后,我們來(lái)看下實(shí)現(xiàn)代碼,如下所示:
// 元素排序 reorder(arr: Array<number>, checkFun: (checkVal: number) => boolean): void { this.end = arr.length - 1; while (this.begin < this.end) { // 向后移動(dòng)begin while (this.begin < this.end && !checkFun(arr[this.begin])) { this.begin++; } // 向前移動(dòng)end while (this.begin < this.end && checkFun(arr[this.end])) { this.end--; } // begin與end都指向了正確的位置 if (this.begin < this.end) { // 交換兩個(gè)元素的順序 [arr[this.begin], arr[this.end]] = [arr[this.end], arr[this.begin]]; } }
測(cè)試用例
我們先來(lái)測(cè)試下奇數(shù)在偶數(shù)之前的函數(shù)處理代碼能否正常執(zhí)行,如下所示:
const adjustArrayOrder = new AdjustArrayOrder(); // 奇數(shù)在前 const arr = [2, 4, 5, 6, 7, 8, 9, 11]; adjustArrayOrder.reorderOddEven(arr); console.log(arr);
執(zhí)行結(jié)果如下所示:
最后,我們來(lái)測(cè)試下reorder函數(shù)能否正常執(zhí)行:
- 負(fù)數(shù)在數(shù)組的最前面
// 負(fù)數(shù)在前 const checkMinusNumber = function (val: number) { return val > 0; }; const arr = [2, 4, 5, 6, 7, -8, -10 - 12, -2]; adjustArrayOrder.reorder(arr, checkMinusNumber); console.log(arr);
- 能被3整除的數(shù)在數(shù)組的最前面
const checkDivisible = function (val: number) { return val % 3 !== 0; }; const arr = [2, 4, 5, 6, 3, 6, 9, 12]; adjustArrayOrder.reorder(arr, checkDivisible); console.log(arr);
示例代碼
文中所舉代碼的完整版請(qǐng)移步:
總結(jié)
到此這篇關(guān)于TypeScript調(diào)整數(shù)組元素順序算法的文章就介紹到這了,更多相關(guān)ts調(diào)整數(shù)組元素順序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- TypeScript 數(shù)組Array操作的常用方法
- TypeScript數(shù)組的定義與使用詳解
- typeScript中數(shù)組類型定義及應(yīng)用詳解
- TypeScript編寫自動(dòng)創(chuàng)建長(zhǎng)度固定數(shù)組的類型工具詳解
- TypeScript實(shí)現(xiàn)數(shù)組和樹(shù)的相互轉(zhuǎn)換
- TypeScript中Array(數(shù)組)聲明與簡(jiǎn)單使用方法
- TypeScript之元組、數(shù)組及as?const的使用
- TypeScript判斷兩個(gè)數(shù)組的內(nèi)容是否相等的實(shí)現(xiàn)
- TypeScript數(shù)組實(shí)現(xiàn)棧與對(duì)象實(shí)現(xiàn)棧的區(qū)別詳解
- TypeScript之元組、數(shù)組、多維數(shù)組定義方法以及 as const說(shuō)明
相關(guān)文章
設(shè)置checkbox為只讀(readOnly)的兩種方式
設(shè)置checkbox為只讀的方法有很多,在本文為大家詳細(xì)介紹下兩種比較實(shí)用的方法,感興趣的朋友不要錯(cuò)過(guò)2013-10-10JavaScript canvas實(shí)現(xiàn)帶有陰影的圖形和文字
這篇文章主要為大家詳細(xì)介紹了JavaScript canvas實(shí)現(xiàn)帶有陰影的圖形和文字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03強(qiáng)悍無(wú)比的WEB開(kāi)發(fā)好助手FireBug(Firefox Plugin)
強(qiáng)悍無(wú)比的WEB開(kāi)發(fā)好助手FireBug(Firefox Plugin)...2007-01-01JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法示例
這篇文章主要介紹了JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法,結(jié)合實(shí)例形式分析了JavaScript使用createElement()方法針對(duì)頁(yè)面元素進(jìn)行動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-04-04JavaScript引用類型Object常見(jiàn)用法實(shí)例分析
這篇文章主要介紹了JavaScript引用類型Object常見(jiàn)用法,簡(jiǎn)單描述了javascript基本數(shù)據(jù)類型,并結(jié)合實(shí)例形式分析了引用類型Object基本創(chuàng)建、賦值、訪問(wèn)屬性等基本操作技巧,需要的朋友可以參考下2018-08-08JS腳本實(shí)現(xiàn)動(dòng)態(tài)給標(biāo)簽控件添加事件的方法
這篇文章主要介紹了JS腳本實(shí)現(xiàn)動(dòng)態(tài)給標(biāo)簽控件添加事件的方法,結(jié)合實(shí)例形式分析了javascript添加事件監(jiān)聽(tīng)的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-06-06淺析微信小程序modal彈窗關(guān)閉默認(rèn)會(huì)執(zhí)行cancel問(wèn)題
這篇文章主要介紹了小程序modal彈窗關(guān)閉默認(rèn)會(huì)執(zhí)行cancel方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10