朋友面试的时候一道面试题,感觉挺有意思的就来实现下。
首先我们来题目的意思是用abc排4个数,然后只能有2个数重复,有多少种排法?
比如:abca,abcb,abcc,acba
要形成这样的4位数,我们可以在abc中插入a或者b或者c;达到aabc,abac,abca。
思路有了,下面来看看怎么实现。
我们首先需要知道abc在不重复的情况下能够组合几种,abc,acb,bac,bca,cab,cba;6种模式。
然后遍历原数据abc,依次获取a或b或c,插入到已经的几种混排的方式中国,因为我们要形成4位数,所以我们遍历4次,插入的位置依次为0,1,2,3.
但是因为 abc,在0的位置插入a,和1的位置插入a,都是aabc,所有有些会是重复的,用new Set()来去重。最后输出结果。方法有了下面我们来看看代码怎么实现
//初始变量
let array=[]; //输出数组
let str='abc'; //原数据
let len=4; //排列的位数
let b=str.split(''); //把原数据变为数组
let cross=conversion(permutate(str)).length; //获取原数据交叉的不重复的数组
使用递归处理字符串有多少种交叉方式
/**
*
*
* @param {any} str //'abc'
* @returns
*/
function permutate(str){
var result=[];
if(str.length==1){
return [str]
}else{
var preResult=permutate(str.slice(1));
for(var j=0;j<preResult.length;j++){
for(var k=0;k<preResult[j].length+1;k++){
var temp=preResult[j].slice(0,k)+str[0]+preResult[j].slice(k);
result.push(temp)
}
}
return result
}
}
把数据转化
function conversion(len){
let result=[];
for(var i=0;i<len.length;i++){
let arr=len[i];
result.push(arr.split(''))
}
return result
}
for(var e=0;e<cross;e++){ //获取几种混排方式
for(var i=0;i<b.length;i++){ //获取a,b,c
for(var c=0;c<len;c++){ //len 形成4位数的数据,依次插入数据
let getArr=conversion(permutate(str));
let _str=b[i],arr=[]; //_str获取a,b,c
arr=getArr[e]; //获取交叉下标为0
arr.splice(c,0,_str); //然后在数组中插入数据
array.push(arr.toLocaleString()); //然后把数据转字符串
}
}
}
console.log(new Set(array)); //去除重复添加的数据
Set {
'a,a,b,c',
'a,b,a,c',
'a,b,c,a',
'b,a,b,c',
'a,b,b,c',
'a,b,c,b',
'c,a,b,c',
'a,c,b,c',
'a,b,c,c',
'b,a,a,c',
'b,a,c,a',
'b,b,a,c',
'b,a,c,b',
'c,b,a,c',
'b,c,a,c',
'b,a,c,c',
'b,c,a,a',
'b,b,c,a',
'b,c,b,a',
'b,c,a,b',
'c,b,c,a',
'b,c,c,a',
'a,a,c,b',
'a,c,a,b',
'a,c,b,a',
'a,c,b,b',
'c,a,c,b',
'a,c,c,b',
'c,a,a,b',
'c,a,b,a',
'c,b,a,b',
'c,a,b,b',
'c,c,a,b',
'c,b,a,a',
'c,b,b,a',
'c,c,b,a' }
console.log(new Set(array).size); //返回数组的长度 36
主要的是思路是在数据中插入一个数据,围绕这个来扩展开来。也希望大家指点错误,最后也希望大家喜欢,可以加入qq群439667347,大家一起讨论,一起进步,后续更新中...