2016 06 09 12 25
尾递归-------怎样将递归改为尾递归 使用lambda表达式
http://www.cnblogs.com/JeffreyZhao/archive/2009/04/01/tail-recursion-explanation.html
博客。
尾递归就是用变量以参数的形势在函数中传递
将上一次的执行结果“全部保存”下来,传递到后一次的执行当中。
??斐波那契数列
public static int FibonacciTailRecursively(int n, int acc1, int acc2)
{
if (n == 0) return acc1;
return FibonacciTailRecursively(n - 1, acc2, acc1 + acc2);
}
FibonacciTailRecursively(10, 0, 1)
??
public static int FactorialContinuation(int n, Func<int, int> continuation)
{
return FactorialContinuation(n - 1,
r => continuation(n * r));
}
//C#中的方法
尾递归改为迭代。
八皇后问题。
????????????????????????
#include <iostream>
using namespace std;
int c[20], n=8, cnt=0;
void print(){
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
if(j == c[i]) cout<<"1 ";
else cout<<"0 ";
}
cout<<endl;
}
cout<<endl;
}
void search(int r){
if(r == n){
print();
++cnt;
return;
}
for(int i=0; i<n; ++i){
c[r] = i;
int ok = 1;
for(int j=0; j<r; ++j)
if(c[r]==c[j] || r-j==c[r]-c[j] || r-j==c[j]-c[r]){
ok = 0; 在实现的过程中,要怎样减枝
break;
}
if(ok) search(r+1); 在程序的阶段,回溯法,首先要确定什么情况下回溯
}
}
int main(){
search(0);
cout<<cnt<<endl;
return 0;
}
01 struct Queen { //皇后类 02 int x, y; //皇后在棋盘上的位置坐标 03 Queen ( int xx = 0, int yy = 0 ) : x ( xx ), y ( yy ) {}; 04 bool operator== ( Queen const& q ) const { //重载判等操作符,以检测不同皇后之间可能的冲突 05 return ( x == q.x ) //行冲突(这一情况其实并不会发生,可省略) 06 || ( y == q.y ) //列冲突 07 || ( x + y == q.x + q.y ) //沿正对角线冲突 08 || ( x - y == q.x - q.y ); //沿反对角线冲突 09 } 10 bool operator!= ( Queen const& q ) const { return ! ( *this == q ); } //重载不等操作符 11 };
01 void placeQueens ( int N ) { //N皇后算法(迭代版):采用试探/回溯的策略,借助栈记录查找的结果 02 Stack<Queen> solu; //存放(部分)解的栈 03 Queen q ( 0, 0 ); //从原点位置出发 04 do { //反复试探、回溯 05 if ( N <= solu.size() || N <= q.y ) { //若已出界,则 06 q = solu.pop(); q.y++; //回溯一行,并继续试探下一列 07 } else { //否则,试探下一行 08 while ( ( q.y < N ) && ( 0 <= solu.find ( q ) ) ) //通过与已有皇后的比对 09 { q.y++; nCheck++; } //尝试找到可摆放下一皇后的列 10 if ( N > q.y ) { //若存在可摆放的列,则 11 solu.push ( q ); //摆上当前皇后,并 12 if ( N <= solu.size() ) nSolu++; //若部分解已成为全局解,则通过全局变量nSolu计数 13 q.x++; q.y = 0; //转入下一行,从第0列开始,试探下一皇后 14 } 15 } 16 } while ( ( 0 < q.x ) || ( q.y < N ) ); //所有分支均已或穷举或剪枝之后,算法结束 17 }
???????????????????????
在程序的开始阶段要初始化程序的必要环境。(如上程序中的 c[20]....)
例如,八皇后问题要先决定储存皇后的数据结构,用栈还是用什么(比如说向量)
在程序的阶段,回溯法,首先要确定什么情况下回溯
在实现的过程中,要怎样减枝。
//回溯法
尝试所有的情况
返回值是bool
可以用一个参数的形式记录下结果
bool Solve(configuration conf)
{
if (no more choices) // BASE CASE
return (conf is goal state);
for (all available choices) {
try one choice c;
// solve from here, if works out, you're done
if (Solve(conf with choice c made)) return true;
unmake choice c;
}
return false; // tried all choices, no solution found
}