主题:关于 排列&组合——深搜解法
faintzw
[专家分:2660] 发布于 2004-08-17 20:35:00
近几天在坛子上见人讨论关于排列和组合的求法,我贴出我的程序,请大家过目
在M$中任选K个字母。
排列:
DECLARE SUB dfs (d!)
CLS
CONST maxn = 100
DIM SHARED a(maxn), used(maxn), l, k, m$
INPUT m$, k
l = LEN(m$)
CALL dfs(1)
SUB dfs (d)
IF d - 1 = k THEN
FOR i = 1 TO k: PRINT MID$(m$, a(i), 1); : NEXT i
PRINT
ELSE FOR i = 1 TO l
IF used(i) = 0 THEN
used(i) = 1
a(d) = i
dfs (d + 1)
used(i) = 0
END IF
NEXT i
END IF
END SUB
组合:
DECLARE SUB dfs (d!)
CLS
CONST maxn = 100
DIM SHARED a(maxn), used(maxn), l, k, m$
INPUT m$, k
l = LEN(m$)
CALL dfs(1)
SUB dfs (d)
IF d - 1 = k THEN
FOR i = 1 TO k: PRINT MID$(m$, a(i), 1); : NEXT i
PRINT
ELSE FOR i = a(d - 1) + 1 TO l '细心的人也许已经发现,组合和排列只在这一处改动了1个数
IF used(i) = 0 THEN
used(i) = 1
a(d) = i
dfs (d + 1)
used(i) = 0
END IF
NEXT i
END IF
END SUB
算法为DFS,深度优先搜索。
欢迎发表意见或建议,新手有不明白也欢迎提问。
回复列表 (共34个回复)
沙发
faintzw [专家分:2660] 发布于 2004-08-17 21:49:00
以上程序是从一道题扩展来的:
输入N、K,输出从1,2,3。。N中选K个数的排列(组合):
DECLARE SUB dfs (d!)
CLS
CONST maxn = 100
DIM SHARED a(maxn), used(maxn), k,n
INPUT n, k
CALL dfs(1)
SUB dfs (d)
IF d - 1 = k THEN
FOR i = 1 TO k: PRINT a(i); : NEXT i
PRINT
ELSE FOR i = 1 TO n '同样只改这里就可以完成 排列到组合 的转化
IF used(i) = 0 THEN
used(i) = 1
a(d) = i
dfs (d + 1)
used(i) = 0
END IF
NEXT i
END IF
END SUB
可以看到,几乎完全一样。
这几个程序可以看出非常明显的深搜框架,想学搜索的可以参考。正是为了这个原因我才发这个主题。
板凳
公孙成 [专家分:1040] 发布于 2004-08-17 21:51:00
好贴!
3 楼
faintzw [专家分:2660] 发布于 2004-08-17 22:56:00
我写的深搜框架(严重建议新手看看……高手就别看了,没什么意义):
'定义数据结构
const maxn=100
dim shared s(maxn) 's,即stack,即栈,用来存结果的。由此,我对 rickone的“BASIC不能用栈”表示怀疑,并且,有时间我会用QBASIC,用栈把那个表达式求值写出来的。难度并不高。我用TP写了140行左右,用BASIC应该可以尽量控制在120行左右。
'DFS子程序
sub dfs(d) 'd,即depth,即深度。
if 现在的结点是目标结点 then 把S中的数输出,就是1组解了
else for k=1 to r 'k为方案编号,在上题中就是1到n
if 方案k符合要求 then
1、设置标记 '上题中就是将used(i)设为1,即已经用过
2、当前状态入栈记录下来
3、dfs(d+1) '递归调用
4、清除标记 '上题中就是将used(i)重新改成0
end if
next k
end if
end sub
总结:深搜不像动态规划那么活,它是有框架的。一般只要确定一个程序可以用深搜,就可以直接套框架。
PS:因为我的深搜是在PASCAL上学的,所以用BASIC描述或许会有些不太清楚,不明白的可以加QQ:155175157,注明是编程
4 楼
rickone [专家分:15390] 发布于 2004-08-17 23:21:00
深搜是不是深度优先搜索的简称?
我还没学过,其实我系统学的东西很少,我只是喜欢编程,只有高一的时候参加过PASCAL语言班,但是学得很浅,那年的竞赛又取消了,所以很遗憾。我只是不断的编东西,脑子里突然出个点子,然后就编。我编的全是有意思的东西;)
什么是堆栈?FILO,first in last out,它的本质是‘线性表’,实现起来不是很简单数组一下搞定,至于为什么叫堆栈,是在对这个线性表的操作上,程序=数据结构+算法 嘛,如果我对这个线性表只对头部进行插入、删除、读取的操作,这不就是栈?
你的那个深搜是对‘图’的操作吗?图这样‘多对多’的复杂的数据结构都能搞定,栈算什么。
其实我的那个算表达式的程序里也有一个Stack(),你没仔细看?我的方法是先把中缀式转化成后缀式,转化的时候就需要一个栈。至于你说的用双栈算表达式,不知道是不是《数据结构》里栈应用的一个例子?我还是喜欢用后缀式。
5 楼
dddduuuu [专家分:80] 发布于 2004-08-17 23:45:00
这才是好程序!
我贴的那个,自己都看不明白!
6 楼
faintzw [专家分:2660] 发布于 2004-08-18 00:22:00
楼上的过奖。
回rickone兄,深搜=depth-first search=深度优先搜索。你那个我是没仔细看的。我并不认为中缀比后缀麻烦,用双堆栈可以很简单解决。tsinghua的绿皮《数据结构》上的确有这样一道题,但我没怎么看。
深搜可以对图,树等很多东东进行遍历,不只图。当然,深搜原本的确是对图的一种遍历方法。
我只是对兄弟你那时说的“那你在BASIC里用栈我看看”表示一下看法而已。现在既然大家都已经能轻易解决那个问题,就不说了吧。
7 楼
Jumping [专家分:120] 发布于 2004-08-18 22:42:00
可否把你那个表达式求值的程序发来看看
Z_Jumping@163.com
8 楼
jinjhl [专家分:50] 发布于 2004-09-08 07:00:00
先顶起来,有空再细看。不过没有注释很难看懂啊。
9 楼
faintzw [专家分:2660] 发布于 2004-09-08 12:40:00
认真看了吗?我在下面有个深搜框架,你直接套框架不就看懂了?
10 楼
jinjhl [专家分:50] 发布于 2004-09-08 20:59:00
希望将深搜的问题细细讲解一下,要深入浅出,好让我等新手能听懂。
最好多举些例子。
我来回复