javascript如何返回字符串的所有排列
js返回字符串的所有排列
需求
返回一個(gè)字符串所有的排列
- 輸入:一個(gè)字符串
- 輸出:一個(gè)包含該字符串所有排列情況的數(shù)組
代碼
const anagrams = str => { if (str.length <= 2) { return str.length === 2 ? [str, str[1] + str[0]] : [str]; } else{ return str.split('').reduce((acc, letter, i) => acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []); } };
效果
一點(diǎn)思路
遞歸、長(zhǎng)度為階乘
js實(shí)現(xiàn)字符串全排序
這是一道經(jīng)典的算法題,學(xué)過(guò)排列組合的童鞋們都知道長(zhǎng)度為n的字符串其全排序大小為n! (這里不考慮字符串里有重復(fù)字符,不做去重處理)。
網(wǎng)上有各種語(yǔ)言的實(shí)現(xiàn)算法,但js語(yǔ)言實(shí)現(xiàn)的比較少(果然藐視【劃掉】忽略我廣大前端er的算法水平)。另外,網(wǎng)上實(shí)現(xiàn)的多為遞歸方法。這里用非遞歸的js實(shí)現(xiàn)一下,輕拍。
先說(shuō)一下思路:?jiǎn)蝹€(gè)字符的串,比如a全排序?yàn)?(廢話忽略)。
兩個(gè)字符的串比如ab,全排序數(shù)為2,即:ab和ba。那我們不禁要問(wèn),你是怎么得到的?
解答如下:
- 第一步————先拿出a,那么a的前面和a的后面產(chǎn)生兩個(gè)空位,如圖:0 a 0。
- 第二步————將b分別放在兩個(gè)空位里,得到ba和ab。
- 第三步————sorry,沒(méi)有第三步。
好了,那三個(gè)字符abc你怎么辦?
其實(shí)還是老辦法,只不過(guò)我們是建立在剛才的2個(gè)字符組成的串已經(jīng)全排完的基礎(chǔ)上。
- 第一步————拿出剛才產(chǎn)生的ba,它產(chǎn)生了三個(gè)空位,如圖:0 b 0 a 0.
- 第二步————把剩余的c分別插入這三個(gè)空位,得到cba,bca和bac。
- 現(xiàn)在我們的ba已經(jīng)被利用完了,還有ab沒(méi)用,ok,我們現(xiàn)在來(lái)用它重復(fù)上面的步驟,得到cab,acb和abc。
那四個(gè)字符abcd組成的串呢?
聰明的你一定想到用剛才三個(gè)字符產(chǎn)生的結(jié)果,每個(gè)串生成4個(gè)空位,然后把d分別放在這4個(gè)空位里。
至此,我們的算法思路就已經(jīng)說(shuō)完了。現(xiàn)在開始用代碼實(shí)現(xiàn)。
function myPermutation(str){ // 空字符串直接返回吧 if(str.length === 0){ console.log('The string you input have No length!'); return; } // 一個(gè)字符也不用運(yùn)算 if(str.length === 1){ console.log('The result array is: ' + str, '-&- The array length is: ' + str.length); return; } // 長(zhǎng)度2以上的開始計(jì)算 /* 先把字符串轉(zhuǎn)成數(shù)組,因?yàn)閖s里關(guān)于字符串的函數(shù)不多,而關(guān)于數(shù)組的函數(shù)很多,所以中間步驟我們都用數(shù)組處理,比較方便 */ var arrayStr = str.split(''); /* 定義一個(gè)中間數(shù)組,作為每次大循環(huán)的根基。比如,你開始拿第3個(gè)字符去填充空位,那前2個(gè)字符的全排列就已經(jīng)都存儲(chǔ)在中間數(shù)組里了 */ // 你開始拿第4個(gè)字符去填充空位,那前3個(gè)字符的全排列就已經(jīng)都存儲(chǔ)在中間數(shù)組里了 var transArray = []; /* 先把字符串的第1個(gè)字符存入中間數(shù)組,這是我們蓋高樓的地基。此字符產(chǎn)生的兩個(gè)空位,我們拿第2個(gè)字符開始去填充 */ transArray.push(arrayStr[0]); // 定義一個(gè)存儲(chǔ)最終結(jié)果的數(shù)組,作為返回值 var resultArray = []; /* 第一層循環(huán),從第2個(gè)字符開始,每次向字符串后取一個(gè)字符,往 中間數(shù)組 的每個(gè)字符串的 空位 里插 */ for(var i = 1; i < arrayStr.length; i++){ resultArray = []; // 每次新取到的字符 var addChar = arrayStr[i]; /* 第二層循環(huán),取一個(gè) 中間數(shù)組里 用以形成空位的 字符串,中間數(shù)組的長(zhǎng)度就是此新字符前面的所有字符形成的全排列個(gè)數(shù) */ for(var j = 0; j < transArray.length; j++){ // 依次取中間數(shù)組里的串 var toBeInsertStr = transArray[j]; // 用空格分割字符串,從而產(chǎn)生空位 var toBeInsertStrArray = toBeInsertStr.split(''); // 第三層循環(huán),將取到的新字符分別放到空位上形成字符串,有多少空位就循環(huán)幾次 for (var k = 0; k <= transArray[j].length; k++){ tempArray = toBeInsertStrArray.concat(); // 用splice函數(shù)處理,表示將字符填入空位 var insertedArray = toBeInsertStrArray.splice(k, 0, addChar); // 剛才是數(shù)組操作,現(xiàn)在轉(zhuǎn)成字符串 var transArrayItem = toBeInsertStrArray.join(''); // 將字符串壓入結(jié)果數(shù)組 resultArray.push(transArrayItem); toBeInsertStrArray = tempArray.concat(); } } transArray = []; transArray = resultArray.concat(); } console.log('The result array is: ' + resultArray, '-&- The array length is: ' + resultArray.length); } myPermutation(''); myPermutation('a'); myPermutation('ab'); myPermutation('abc');
運(yùn)行結(jié)果:
The string you input have No length!
The result array is: a -&- The array length is: 1
The result array is: ba,ab -&- The array length is: 2
The result array is: cba,bca,bac,cab,acb,abc -&- The array length is: 6
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript仿淘寶實(shí)現(xiàn)固定右側(cè)側(cè)邊欄
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)仿淘寶固定右側(cè)側(cè)邊欄效果,文中示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下2022-03-03js中如何將多層嵌套的數(shù)組轉(zhuǎn)換為一層數(shù)組
這篇文章主要介紹了js中如何將多層嵌套的數(shù)組轉(zhuǎn)換為一層數(shù)組問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06ionic+html5+API實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用
這篇文章主要為大家詳細(xì)介紹了ionic+html5+API實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09使用js實(shí)現(xiàn)數(shù)據(jù)格式化
這篇文章主要介紹了使用javascript實(shí)現(xiàn)數(shù)據(jù)格式化為字符串,非常的實(shí)用,這里推薦給有相同需求的小伙伴。2014-12-12moment.js輕松實(shí)現(xiàn)獲取當(dāng)前日期是當(dāng)年的第幾周
這篇文章主要介紹了moment.js輕松實(shí)現(xiàn)獲取當(dāng)前日期是當(dāng)年的第幾周,需要的朋友可以參考下2015-02-02深入淺出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解
下面小編就為大家?guī)?lái)一篇深入淺出webpack教程系列_安裝與基本打包用法和命令參數(shù)詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就想給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09uniApp實(shí)現(xiàn)選擇時(shí)間功能
這篇文章主要介紹了uniApp實(shí)現(xiàn)選擇時(shí)間功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-03-03