reduce
常见的可能就是
// array.reduce(function(total, currentValue, currentIndex, arr), ?initialValue)
[1, 2, 3, 4].reduce((pre, next) => pre + next, 0)
值得注意的是initialValue
如果没传值 , 默认是array
的第一个值,currentIndex
是从1开始的,而不是0开始。
reduce的另外一种场景就是递归。
例如下面的算法题。
定义52张扑克牌(无大小王), 扑克牌需定义花色与数字。 (花色简称: 红桃-H, 梅花-C, 方块-D,黑桃-S)
顺子固定长度为5张牌,不用考虑K之后到A的情况
定义一个函数,让用户选择两张扑克牌, 函数返回所有可能的顺子组合, 如果能形成同花顺,在开始前打印(SF).
如: 调用 searchStraight(D2, D5) ->
打印结果: SF->DA, D2, D3, D4, D5
HA, D2, H3, D4, D5
…
共包含 xxxx 顺子
参考题解:
// test.ts
const HS = ['S', 'H', 'C', 'D'];
const Lab = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
class PK {
hs: string;
label: string;
value: number;
constructor(hs: string, value: number) {
if (value < 0 || value > Lab.length - 1 || HS.indexOf(hs) < 0) {
throw new Error('请输入正确的牌!');
}
this.hs = hs;
this.value = value;
this.label = Lab[value];
}
}
const searchStraight = (input1: string, input2: string) => {
if (Object.prototype.toString.call(input1) !== '[object String]' ||
Object.prototype.toString.call(input2) !== '[object String]'
) {
throw new Error('请输入正确的牌!');
}
const pk1 = new PK(input1.substring(0, 1), Lab.indexOf(input1.substring(1)))
const pk2 = new PK(input2.substring(0, 1), Lab.indexOf(input2.substring(1)))
const smaller = pk1.value > pk2.value ? pk2 : pk1;
const bigger = pk1.value > pk2.value ? pk1 : pk2;
const result: PK[][] = [];
const min = bigger.value - 4 < 0 ? 0 : bigger.value - 4;
const max = smaller.value;
for (let value = min; value <= max; value++) {
result.push(...createArr5(value, smaller, bigger))
}
result.forEach(sz => {
if (pk1.hs == pk2.hs && sz.filter(pk => pk.hs === pk1.hs).length === 5) {
console.log(`SF-->${sz.map(pk => pk.hs + pk.label).join(',')}`)
} else {
console.log(sz.map(pk => pk.hs + pk.label).join(','))
}
})
console.log(`共包含 ${result.length} 顺子`)
}
const createArr5 = (value: number, smaller: PK, bigger: PK) => {
const indexArr = new Array(5).fill('')
return indexArr.reduce<PK[][]>((previousValue, _, currentIndex) => {
const result: PK[][] = [];
if (currentIndex === 0) {
if (smaller.value === value) {
result.push([new PK(smaller.hs, value)]);
} else {
for (let i = 0; i < HS.length; i++) {
const hs = HS[i];
result.push([new PK(hs, value)]);
}
}
} else {
for (let j = 0; j < previousValue.length; j++) {
const element = [...previousValue[j]];
const currentValue = value + currentIndex
if (currentValue === smaller.value) {
result.push([...element, new PK(smaller.hs, currentValue)]);
} else if (currentValue === bigger.value) {
result.push([...element, new PK(bigger.hs, currentValue)]);
} else {
for (let i = 0; i < HS.length; i++) {
const hs = HS[i];
result.push([...element, new PK(hs, currentValue)]);
}
}
}
}
return result;
}, [])
}
searchStraight('S8', 'SJ')
上面主要的算法就在createArr5
,利用reduce去递归,比起正常递归调用,思路更加清晰, 每一步结果一个自动传下去;
思路就是:
顺子就是一个排列组合问题,
更具输入的input1
和input2
计算出边界;然后计算每一种顺子不同花色的排列组合;顺子的长度相当于for循环的层数 ,也就是递归的次数;