1.逆波兰表达式
一种把运算符前置的算数表达式(特点运算符之间不必有优先级关系)
#include <iostream>
#include <cstdio>
using namespace std;
float atof(char *c)
{
float d;
sscanf(c,"%f",&d); //将字符转化为对应的整数;
return d;
}
double ys()
{
char a[10];
scanf("%s" ,a); //输入字符串a;
switch (a[0]) //遇到运算符返回后两个进行运算;
{
case '+': return ys()+ys();
case '-': return ys()-ys();
case '*': return ys()*ys();
case '/': return ys()/ys();
default: return atof(a);
}
}
int main()
{
double sum;
sum=ys(); //调用函数
printf("%.6f" ,sum); //输出保留小数点后6位的数;
return 0;
}
小结:首先递归的终止是读取终止符,其次是递归的方式是遇到运算符返回后两位进行运算,最后<stdio.h>中的sscanf函数:从字符串中读进与指定格式相符的数据。
2.全排序:输出给定字符串的所有全排序,并已知给定的是从小到大排序的。
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
string str[722]; //全局变量;
int a=0;
void pe(char *l,int k, int m)
{
if(k==m)
{
str[a]=l;
a++;
}
else
for(int j=k;j<=m;j++)
{
swap(l[k],l[j]); //交换函数;
pe(l,k+1,m);
swap(l[k],l[j]);
}
}
int main()
{
char l[10];
int m;
scanf("%s",l);
m=strlen(l); //读取给定字符串的长度;
pe(l,0,m-1);
sort(str,str+a); //将所得的结果进行从小到大排序;
for(int i=0;i<a;i++)
cout<<str[i]<<endl;
return 0;
}
总结:首先递归思想一串字符串进行排序,首先定一个在头部然后后面在进行排序,递归每定一个排的方式减少,但只剩最后一个字符就只有一种排法,为递归的终止条件。运用swap函数,中的strlen函数:计算给定字符串的(unsigned int)长度,sort函数:排序函数,默认从小到大。
3.Pell数列:a1=1,a2=2,…an=2*a(n-1)+a(n-2).求pell数列的第K项模上32767是多少。
#include <iostream>
#define m 1000005 //宏定义命令;
using namespace std;
long long a[m]={0};
long long fbnq(int n)
{
if(a[n]!=0) //记忆化递归;
return a[n];
if(n==1) return 1;
if(n==2) return 2;
else return a[n]=(fbnq(n-1)*2+fbnq(n-2))%32767; //给定递归的规则;
}
int main()
{
long long n,i;
cin>>n;
long long b[n],c[n];
for(i=0;i<n;i++)
{
cin>>b[i];
c[i]=fbnq(b[i]);
}
for(i=0;i<n;i++)
{
cout<<c[i]<<endl;
}
return 0;
}
总结:首先题目给出咯递归规则(an=z*a(n-1)+a(n-2)),但直接用递归会超时,所以得将递归记忆化。
4.爬楼梯:每次可以走1级或者2级,输入楼梯的级数,求不同的走法数。
#include <iostream>
#include <stdio.h>
using namespace std;
int zf(int n)
{
if(n>2)
return zf(n-1)+zf(n-2); //递归调用;
else return n;
}
int main()
{
int n=0,b[30],c[30];
while(cin>>b[n])
n++;
for(int i=0;i<n;i++)
c[i]=zf(b[i]);
for(int j=0;j<n;j++)
cout<<c[j]<<endl;
return 0;
}
总结:递归的规则递归的规则,总共的方法等于每次走一梯,加上每次走两梯的方法,即f(n)=f(n-1)+f(n-2).此题的关键就在于找这递归规则。
5.放苹果:把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
#include <iostream>
using namespace std;
int f(int m,int n)
{
if(n==0) return 0;
if(m==0||n==1) //递归的终止条件就m=0或n=1;
return 1;
else if(m>=n)
return f(m-n,n)+f(m,n-1); //递归即返回每个盘子都放的方法加上有盘子为空盘的方法;
else return f(m,m);
}
int main()
{
int t,i,m,n,b[20];
cin>>t;
for(i=0;i<t;i++)
{
cin>>m>>n;
b[i]=f(m,n);
}
for(i=0;i<t;i++)
cout<<b[i]<<endl;
return 0;
}
总结:递归的终止条件为苹果为零时或盘子数为1时,递归终止;递归规则,总数为每个盘子都放有苹果的总数(f(m-n,n))加上有空盘子的情况下的总数(f(m,n-1))。
6.分解因数:给出一个正整数a,要求分解成若干个正整数的乘积,即a = a1 * a2 * a3 * … * an,并且1 < a1 <= a2 <= a3 <= … <= an,问这样的分解的种数有多少。注意到a = a也是一种分解。
#include<iostream>
using namespace std;
int fy(int m,int n)
{
int a=1; //为本身的那种情况;
if(n==1) return 0; //递归终止条件;
for(int i=m;i*i<=n;i++) //从2开始遍历找所有的能分解的情况;
if(n%i==0)
{
a=a+fy(i,n/i); //递归返回找更大的因数;
}
return a;
}
int main()
{
int n;
cin>>n;
int b[n],c[n];
for(int i=0;i<n;i++)
{
cin>>b[i];
c[i]=fy(2,b[i]);
}
for(int j=0;j<n;j++)
cout<<c[j]<<endl;
}
总结:主要是递归规则的寻找,从最小的2开始,一一找出所有的因数。较大的因数还可分解为更小的因数的存在,当为全为最小的因数组时为最后一种情况。
7.2的幂次方表示:任何一个正整数都可以用2的幂次方表示。
#include <iostream>
#include <cmath>
using namespace std;
void f(int n)
{
int i=0;
if(n==1)
{
cout<<"2(0)";
return ;
}
if(n==2)
{
cout<<"2";
return ;
}
while(pow(2,i)<=n) //从能找出2的最大的幂次方表示;
i++;
cout<<"2";
if(i>2) //将较大的幂在进行进一步的分解为2的幂次方表示;
{
cout<<"(";
f(i-1);
cout<<")";
}
if(n-pow(2,i-1)!=0)
{
cout<<"+";
f(n-pow(2,i-1));
}
}
int main()
{
int n;
cin>>n;
f(n);
}
总结:此题是开始找出最接近或是等于n的2的幂次方,然后剩下的数在寻找小一点的2的幂次方,以此递归下去。
总的的来说就是难以形成 递归的思想,和寻找递归的规则。期待之后能将递归思想贯穿于脑海。