递归和迭代的区别及关系_c语言递归函数的例子「建议收藏」

递归和迭代的区别及关系_c语言递归函数的例子「建议收藏」题目和原解法原文用py和循环15步完成,其实这个比较简单,没啥可玩的,重点在于思路状态由三个,不能使用位运算,但是可以使用十进制的每个位首先用数组表示实属有点浪费,哪怕是字符串呢,不过数组确实操作方便,这个题目的搜索难

题目和原解法

a1217ccda1b6629bbb90161448a53905.png

原文用py和循环15步完成, 其实这个比较简单, 没啥可玩的, 重点在于思路

状态由三个, 不能使用位运算, 但是可以使用十进制的每个位

首先用数组表示实属有点浪费, 哪怕是字符串呢, 不过数组确实操作方便, 这个题目的搜索难度也不大所以用啥都行, 最好是封装位运算或者字符串, 这样判断是否阻塞也方便

67dae6e6a406c88eec1762849bc07bff.png

对于每一次搜索, 所有可以进行的操作就是一步, 然后深搜即可, 每进一步执行操作更新状态, 每撤销一步恢复状态, 由于状态就是数字, 不会有引用问题

由于每次操作数目有限, 目测应该是指数级

本来不想写的… 不过实在没啥事干就用js实现下吧…

深搜简单实现下, 每加阻塞判断和优化, 跑出来的结果也是15, 一共只有两个解… 原文中给的是第二个解

[

[

2223133, 2213233, 2123233,

2321233, 2323213, 2323231,

2323132, 2313232, 1323232,

3123232, 3321232, 3323212,

3323122, 3313222, 3331222

],

[

2212333, 2232133, 2232313,

2231323, 2132323, 1232323,

3212323, 3232123, 3232321,

3232312, 3231322, 3132322,

3312322, 3332122, 3331222

]

]

const white = 2

const blank = 1

const black = 3

const moveType = {

left: 0, // 左移

leftJump: 1, // 左跳

right: 2, // 右移

rightJump: 3, // 右跳

}

// 由低位到高位 1:空格,2:白,3:黑

const show = n => {

console.log(

toList(n)

.reverse()

.join(“-“),

)

}

const toList = n =>

Array(7)

.fill(0)

.map((_, i) => ((n / 10 ** i) | 0) % 10)

/*

2 2 2 1 3 3 3

index 0 1 2 3 4 5 6

value 3 3 3 1 2 2 2

*/

initState = 2221333

show(initState) // 2-2-2-1-3-3-3

// 是否满足终止条件

const check = n => {

return n === 3331222

}

const showStop = n => {

return false

}

const get = (n, index) => ((n / 10 ** index) | 0) % 10

const set = (n, index, value) =>

n – get(n, index) * 10 ** index + value * 10 ** index

const exchange = (n, from, to) => {

const fv = get(n, from)

const tv = get(n, to)

return set(set(n, from, tv), to, fv)

}

const doMove = (n, { type, index }) => {

if (type === moveType.left) {

return exchange(n, index, index + 1)

} else if (type === moveType.leftJump) {

return exchange(n, index, index + 2)

} else if (type === moveType.right) {

return exchange(n, index, index – 1)

} else if (type === moveType.rightJump) {

return exchange(n, index, index – 2)

}

}

const indexArray = Array(7)

.fill(0)

.map((_, k) => k)

// 获取可操作的集合

const getOpList = n => {

// 空格所在位置

const blankIndex = indexArray.find(i => get(n, i) === blank)

console.log(“blankIndex”, blankIndex)

const list = []

for (let i = 0; i < 7; i++) {

if (i === blankIndex) continue

if (get(n, i) === black) {

if (i + 1 < 7 && i + 1 === blankIndex) {

// 黑左移

list.push({

type: moveType.left,

index: i,

})

} else if (i + 2 < 7 && get(n, i + 1) === white && i + 2 === blankIndex) {

// 黑左跳

list.push({

type: moveType.leftJump,

index: i,

})

}

} else {

if (i >= 1 && i – 1 === blankIndex) {

// 白右移

list.push({

type: moveType.right,

index: i,

})

} else if (i >= 2 && get(n, i – 1) === black && i – 2 === blankIndex) {

// 白右跳

list.push({

type: moveType.rightJump,

index: i,

})

}

}

}

return list

}

// 是否存在阻塞

const shouldStop = () => {}

const answer = []

const dfs = (n, path = []) => {

console.log(“dfs”, n, path.length)

if (check(n)) {

console.log(path.length, path)

answer.push([…path])

return true

}

if (shouldStop(n)) {

// 存在阻塞

return false

}

const list = getOpList(n)

// 获取所有可以执行的操作

for (const op of list) {

// 进行操作

console.log(op)

path.push(doMove(n, op))

const res = dfs(doMove(n, op), path)

path.pop()

if (res) {

// return true

}

}

return false

}

dfs(initState)

console.log(answer)

今天的文章递归和迭代的区别及关系_c语言递归函数的例子「建议收藏」分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88694.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注