递归函数汇总(二)

来源:互联网 发布:黄金时代 知乎 编辑:程序博客网 时间:2024/05/16 05:15

2.求集合的冥集
   代码:
void GetPowerSet1(int i,char a[],char b[],int n)
{
    //功能:求以数组a中元素为集合中元素的集合的冥集
    int j;
    if(i==n-1)
   {
    b[n]='/0';
    for(j=0;j<n+1;j++)
    if(b[j]!=' ') cout<<b[j];     //对空格不输出
     cout<<endl;
   }
    else
    {
        b[i]=a[i]; GetPowerSet(i+1,a,b,n);
       b[i]=' ';   GetPowerSet(i+1,a,b,n);
    }
}
后记:适当改造可以用来求一个字串的所有子串.

3.将任意整数N,分解成多个互不相同的正整数的和,打印所
有可能的组合方式。例如:n=6,组合方式有1+5,2+4,1+2+3。

N=20的例子:
#include <iostream.h>
bool visited[21];
bool c[40];
void get_arr(int b[],int i);
int main()
{
    int i,j,b[20];
    for(i=0;i<21;i++)
    visited[i]=0;
    for(i=0;i<40;i++)
    {
        for(j=2;j<i/2;j++)
        if(i%j==0)
        { c[i]=0;break;}
        if(j==i/2) c[i]=1;
    }
   c[4]=0;
    for(i=1;i<21;i++)
    {
        b[0]=i;
        visited[i]=1;
       get_arr(b,0);
       visited[i]=0;
    }
    return 0;
}

void get_arr(int b[],int i)
{
    int m,j;
    if(i>18)
    {
        if(c[b[0]+b[19]]==1)
        {
            for(m=0;m<20;m++)
            cout<<b[m]<<" ";
            cout<<endl;
       }
    }
    else
    {
      for(j=1;j<21;j++)
      if(visited[j]==0&&c[b[i]+j]==1)
      {
         b[i+1]=j;
       visited[j]=1;
        get_arr(b,i+1);
        visited[j]=0;
      }
    }
}
后记:未遇到相关应用

4.经典的四皇后问题
void Trial(int i,int n,int a[])
{
//n皇后问题 ,初始状态没有棋子(即a={0})
    int col,row,j,flag,k;
    if(i>=n)
    {
 for(col=0;col<n;col++)
    for(row=0;row<n;row++)     //输出最终布局(1代表棋子所在位置)
    {
        cout<<a[col*n+row];
        if(row==n-1) cout<<endl;
    }
    cout<<endl;
    }
    else
    for(j=0;j<n;j++)
    {
        a[i*n+j]=1;
        flag=1;
        //在每个检验中加入了flag是否等于1的判断,以提高速度
        for(col=0;col<n&&flag==1;col++)
        if(a[col*n+j]==1&&col!=i)        //检验行是否符合要求
        {flag=0;break;}
        for(row=0;row<n&&flag==1;row++)
        if(a[i*n+row]==1&&row!=j)       //检验列
        {flag=0;break;}
        for(k=i+j,col=k-n+1,row=n-1;col<n&&flag==1;row--,col++)
        if(a[col*n+row]==1&&col!=i)     //检验主对角线
          {flag=0;break;}
       if(flag==1)
       {
        //检验副对角线,分情况检验
        if(i<j)
        {
          for(k=i>j?i-j:j-i,col=0,row=k;row<n;row++,col++)
          if(a[col*n+row]==1&&col!=i)
            {flag=0;break;}
        }
        else
        {
       for(k=i>j?i-j:j-i,col=k,row=0;col<n;row++,col++)
          if(a[col*n+row]==1&&col!=i)
            {flag=0;break;}
        }
       }
      if(flag==1) Trial(i+1,n,a);
            a[i*n+j]=0;
    }
}

5.分治法.简言之,就是把一个复杂的问题分成两个或更多的相同或相似的子问题.以此递归

int fun(int a[],int n,int x)
{
    //功能:求n次多项式的值,a[i]为x的i次方的常数项
    if(n==0)   return    (a[i]*x);
    else
    return (x*(fun(a,n-1,x)+a[i]));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//hanoi问题
int count=0;
void move(char x,char y)
{
    printf("%c--->%c/n",x,y);
    count++;
}

void hanoi(int n,char one,char two,char three)
{
    //将n个盘从one座借助two座,移到three座
    if(n==1) move(one,three);
    else
    {
        hanoi(n-1,one,three,two);
        move(one,three);
        hanoi(n-1,two,one,three);
    }

 

递归函数在解决复杂算法方面有很大的作用,比如著名的quicksort就是使用递归实现的.用好了它,可以事半公倍的帮你解决问题..