简单递归
一、输入{[2,3,6,7], 7},输出{[2,2,3], [7]}。解释:从数组中选取和是给定值的组合,数组元素是不重复的正整数。
令K代表当前的差距,A代表当前可选择数字序列的起始位置,N代表从A开始有多少个数字可供选择。那么只需要不断选择一个数字,更新A,N,K,然后再选一个数,直到K=0,说明找到了一个序列。
F(A,N,K)
IF K = 0:Accept tmp[] and return
FOR T←[N..A.Length], step←1:
IF A[T] <= K:
tmp.APPEND A[T]
F(A, T, K-A[T])
tmp.POP
FI
二、输入2,输出{()(), (())}。解释:计算N组括号的有效组合。
序列中的一个位置要么是左括号,要么是右括号。用辅助函数_F(L,R)指明需要从当前位置写入L个左括号和R个右括号,主过程F调用_F(N,N)。L>R说明括号不匹配。R=0则接受序列。然后根据L和R的关系选择该处可以是左括号还是右括号。
_F(L, R):
IF R=0:Accept and return
IF L > 0:save X; buf[X++] ← '('; _F(L-1,R); restore X;
IF R > L:buf[X++] ← ')'; _F(L, R-1)
F(N): _F(N,N)
性能:N=17时用时3.64秒,还行吧。
三、N皇后问题。N小于10。
假设前M-1行已经放置了皇后Q[1..m-1],现在要向第M行放置皇后Q[m]。将Q[m]依次放到第M行的各列,检查Q[m]是否和Q[1..m-1]冲突,若不冲突则向第M+1行放置Q[m+1]。以此类推,直到发现M>N。
_F(M, N):
IF M>N :Accept and return
FOR S←[1..N] step←1:
PUT(Q_m, M,S)
IF OK:_F(M+1, N)
PICKUP(Q_m)
F(N): _F(0, N)
四、全排列。给定含有N个不重复整数的序列A,计算其所有排列方式。
F(A,N):
IF (X = N): Accept and return
FOR S←[0..N] step←1:
IF 0=visited[S]:
buf[X++] ← A[S]
set visited[S],F(A, N),clear visited[S]
X←X-1
FI
五、幂集。输入A={a,b,c},输出A`={{a,b,c},{a,b},{b,c},{a,c},{a},{b},{c},Φ}。
F(A,N):
IF N=0:Accept and return
buf[X] ← A[N-1]
X←X+1,F(A, N-2)
X←X-1,F(A, N-2)