-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[js] 对数组元素进行排列组合 #8
Comments
var a = [1, 2, 3, 4];
function groupSplit(arr, size) {
var maxSize = arr.length, groupArr = [];
if(size >= 1 && size <= maxSize){
getArr(arr, 0, []);
}
function each(arr, index, fn){
for (var i = index; i < maxSize; i++) {
fn(arr[i], i, arr);
}
}
function getArr(arr, _size, _arr, index){
if(_size === size){
return;
}
var len = _size + 1;
each(arr, index || 0, function(val, i, arr){
_arr.splice(_size, 1, val);
if(_size === size - 1){
groupArr.push(_arr.slice());
}
getArr(arr, len, _arr, i + 1);
});
}
return groupArr;
}
var ret = groupSplit(a, 2);
console.log(ret); // [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]] |
//夏神的代码
var a = [1,2,3,4,5];
function groupSplit(arr ,size) {
var result = [];
+function(arr ,size, comArr) {
var templateArr = [];
for(var i = 0; i < arr.length; i++) {
templateArr = [];
if(comArr instanceof Array) {
if(comArr[comArr.length - 1] < a[i]) {
templateArr = comArr.concat(a[i]);
if(size === 1) {
result.push(templateArr);
} else {
arguments.callee( arr, size - 1, templateArr);
}
}
} else {
templateArr.push(arr[i]);
arguments.callee( arr, size - 1, templateArr);
}
}
}(arr,size);
return result;
}
console.log(groupSplit(a,4)); |
var arr = [10, 11, 12, 13, 14, 15, 16,17, 18];
groupSplit(arr, 4);
function groupSplit(arr, size) {
if(!(typeof arr === 'object' && Object.prototype.toString.call(arr)==='[object Array]')){
throw new TypeError('arguments[0] of function groupSplit is not a array');
}
if(!(typeof size === 'number')){
throw new TypeError('arguments[1] of function groupSplit is not Number Type');
}
if(size < 1){
throw new Error('arguments[1] of function groupSplit should be greater-than 0');
}
var leng = arr.length,
bigArr = [],
lay = new Array(size);
size = Math.floor( Math.min(size, leng) );
for(var i=0; i<size; i++){
var smallResult = smallIndex(arr, size, i) ;
bigArr.push(smallResult);
lay[i]=0;
}
var loopNum=0;
var group = [];
(function loop(loopNum, lay){
var current = loopNum;
loopNum++;
for(lay[current]=0; lay[current]<=leng-size; lay[current]++){
if(loopNum===size){
var small = [];
small[0] = bigArr[0][lay[size-1]].value;
for(var j=1; j<size; j++){
if(bigArr[j][lay[size-j-1]].index > bigArr[j-1][lay[size-j]].index){
small.push( bigArr[j][lay[size-j-1]].value );
}
}
if(small.length===size){
group.push(small);
//document.write(small[0]+'*'+small[1]+'*'+small[2]+'*'+small[3]+'<br/>');
}
}
else if(loopNum < size){
loop(loopNum, lay);
}
}
}(loopNum, lay));
return group;
}
function smallIndex(arr, size, start){
var small = [],
leng = arr.length;
for(var i=start; i<=leng-size+start; i++){
small.push({index:i, value:arr[i]});
}
return small;
} |
var cache = {};
function groupSplit (arr, size) {
if (Object.prototype.toString.call(arr) !== '[object Array]') throw new Error('Please pass a valid array as the first argument');
if (arguments.length !== 2) throw new Error('Please check your arguments, which should be arr and size');
if (isNaN(size)) throw new Error('The second parameter should be an interger');
if (size < 0 || size > arr.length) throw new Error('Size parameter is illegal');
var result = [],
tmp = [],
l = arr.length,
key = arr.join('&') + '_' + size;
if (key in cache) return cache[key];
(function (arr, size, current){
if (size == 0) {
result.push(tmp.slice(0));
} else {
for (var j = current; j < l; j++) {
tmp.push(arr[j]);
arguments.callee.call(null, arr, size-1, j+1);
tmp.pop();
}
}
})(arr, size, 0);
return (cache[key] = result);
}; |
function groupSplit (arr, size) {
var r = []; //result
function _(t, a, n) { //tempArr, arr, num
if (n === 0) {
r[r.length] = t;
return;
}
for (var i = 0, l = a.length - n; i <= l; i++) {
var b = t.slice();
b.push(a[i]);
_(b, a.slice(i + 1), n - 1);
}
}
_([], arr, size);
return r;
} |
help |
@VaJoy 觉得你的实现方法很棒,但是在for循环那里,b=t.slice(),不是很懂,slice()方法不带参数的话不是可以直接去掉吗,但是我去掉之后,又出现了错误,求讲解 |
@yinyanli |
原来是这样,这种方式拷贝真是机智,超级感谢 |
/**
* 排列组合
* @param {[type]} arr [数组]
* @param {[type]} selectNum [剩余的选择的个数]
* @param {[type]} selectedArr [已选择的元素组成的数组]
* @return {[type]} [description]
*/
function getArrange(arr, selectNum, selectedArr) {
if (selectNum === 1) {
for (var i = 0; i < arr.length; i++) {
var newSelectedArr = selectedArr.slice();
newSelectedArr.push(arr[i]);
console.log(newSelectedArr);
}
} else {
selectNum -= 1; //剩余选择的减一
for (var i = 0; i < arr.length; i++) {
var newSelectedArr = selectedArr.slice();
var newArr = arr.slice();
newSelectedArr.push(arr[i]);
newArr.splice(i, 1); //删除push进去的那一个
getArrange(newArr, selectNum, newSelectedArr);
}
}
} 牛刀小试。 |
关于 @VaJoy 的方法是这样的 以 [1,2,3,4] 为例子, size = 3
最后输出 [1,2,3] [1,2,4] [1,3,4] [2,3,4] 每一层都是一次递归, 不断的从右边的数组中拿数字到左边的数组,每次递归size--,当size为0的时候就取左边拿好的数组,为了避免重复,每次取数组的时候都会从左边数组之后开始取。 |
你这个只适用于size小于等于数组长度的情况下,如果要的size大于arr的长度就不行了。 @VaJoy |
排列组合 既然有 所以 题目是不是应该改为 我的答案 function groupSplit(arr: number[], size: number) {
if (size > arr.length) {
throw Error(`"size" should less then ${arr.length}`)
}
const result: number[][] = [];
(function loop(unselectedList: number[], selectedList: number[] = []) {
unselectedList.forEach((selected, i) => {
const newSelectedList = [...selectedList, selected];
const newUnselectedList = unselectedList.filter((_, j) => j > i);
if (newSelectedList.length === size) {
result.push(newSelectedList);
return;
}
loop(newUnselectedList, newSelectedList);
});
})(arr);
return result
}
console.log(
groupSplit([1, 2, 3, 4, 5], 3)
)
// --->
// [ [ 1, 2, 3 ],
// [ 1, 2, 4 ],
// [ 1, 2, 5 ],
// [ 1, 3, 4 ],
// [ 1, 3, 5 ],
// [ 1, 4, 5 ],
// [ 2, 3, 4 ],
// [ 2, 3, 5 ],
// [ 2, 4, 5 ],
// [ 3, 4, 5 ] ] |
function groupSplit(arr, size) {
let result = [];
function createTree(rootArr, remainArr, size) {
if (remainArr.length <= 0 || size === 0) {
result.push(rootArr);
return;
}
for(let i=0; i<= remainArr.length-size; i++) {
const root = remainArr[i];
const other = remainArr.slice(i + 1);
createTree(rootArr.concat(root), other, size - 1);
}
}
createTree([], arr, size);
return result;
}
console.log(groupSplit([1, 2, 3, 4, 5], 3)); |
function getGroup(arr, order) {
if (order === 1) return arr;
let result = [], length = arr.length;
for (let i = 0; i < length; i++) {
const p = arr[i];
const remaining = arr.slice(i + 1);
if (remaining.length < order - 1) break;
result = [
...result,
...getGroup(remaining, order - 1).map(e => [p].concat(e))
];
}
return result;
}
console.log(getGroup([1, 2, 3, 4], 2));
console.log('\n');
console.log(getGroup([1, 2, 3, 4, 5], 3)); |
function groupSplit(arr, size, index = 0, results = [], ...tmp) {
for (let i = index; i < arr.length; i++) {
groupSplit(arr, size- 1, i + 1, results, ...tmp, arr[i])
}
return size ? results : results.push(tmp)
}
console.log(groupSplit([1,2,3,4],2)) |
The text was updated successfully, but these errors were encountered: