特点
递归求字符串长度
- 首先,求整个串的长度,stringLen§
- 再求去掉第一个字符的串长度,stringLen(p+1)
- 依次展开,直至遇到出口*p==0
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7c090095b4ce485188bfe877b0c8c439.png#pic_center)
代码
int stringLen(const char* p){
if(p==0)
return 0;
if(*p==0)
return 0;
return 1+stringLen(p+1);
}
字符串大小比较-递归
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ddc373724bb7437090ba133a8c2bcdb3.png#pic_center)
- 寻找规律,先从第一个字符开始比较,如果相同就比较第二个
- 相似性,比较字符,如果相等,就把问题抛给下一个,谁大谁小由下一个字符决定。
- 出口,先遇到结束标志’\0’,说明串短,属于小的。
- 如果都到了结束标志’\0’,说明相等
代码
#include<iostream>
using namespace std;
int strcmp(const char* a,const char* b){
if(*a=='\0' && *b=='\0')
return 0;
if(*a=='\0')
return -1;
if(*a=='\0')
return 1;
if(*a != *b)
return *a - *b;
return strcmp(a+1,b+1);
}
int main(){
cout << strcmp("abed","abdc")<<endl;
return 0;
}
冒泡排序-递归
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ff5e664edd214234a5d3d88afbe0b771.png#pic_center)
- 冒泡排序过程(从小到大),从第一个元素开始,相邻元素相互比较,如果比后面的数大,则交换。再与后面的元素比较,一轮下来之后,最后一个元素最大。如上图,9比7大,交换。9与3比较,大则交换。9比6大,又交换。9比11小,位置不变。
- 数组的元素个数为n,则第一个循环需比较n-1次,下个循环比较n-2次,最后剩1个元素,则不用比较,是出口。
- 相似性构造,sort(a,n)表示a数组的n个元素进行冒泡排序,第一回把最大的排到最右边,剩下的n-1个元素进行冒泡排序便是sort(a,n-1)。把加黑的功能由另一个递归函数实现。
- 第一回把最大的排到最右边,n个元素相邻的相互比较,需要比较n-1次,构造一个比较交换函数sort_branch(a,n-1),它的含义为a数组的n个元素比较n-1次,大的交换到后面。
- 递归实现sort_branch(a,n-1),第一个元素与第二个比较,大则交换,否则不变。比较一次后,把问题交给下一个,下个从第二个数组元素开始,数组的个数少一个,即sort_branch(a+1,n-2)。相邻比较的特点是最少有2个元素,比较1次。如果数组只有1个元素,那就比较0次,函数的出口。
代码
#include<iostream>
using namespace std;
void swap(int* a,int* b){
int c=*a;
*a=*b;
*b=c;
}
void sort_branch(int *a,int n){
if(n==0)
return;
if(a[0]>a[1])
swap(a[0],a[1]);
sort_branch(a+1,n-1);
}
void sort(int *a,int n){
if(n==1)
return;
sort_branch(a,n-1);
sort(a,n-1);
}
void show(int* a,int n){
if(n==0)
return;
cout<<*a<<" ";
show(a+1,n-1);
}
int main(){
int a[]={9,7,12,5,65,99,15};
int n=sizeof(a)/sizeof(int);
sort(a,n);
show(a,n);
return 0;
}
爬台阶-间接调自己
题目
- 如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完n级台阶,有多少种不同的上法呢
方法一
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/50a81ec2d2764997a5d369bf45dd4b0c.png#pic_center)
- 总步数是偶数步,做2个递归函数,n阶台阶偶数步爬完的种数为climb_stairs_even(int n),n阶台阶奇数步爬完的种数为climb_stairs_odd(int n)
- 总步数是偶数步,故函数从偶数开始,然后是奇数步。
- 出口就是1、2个台阶分别对应的奇偶数步
#include<iostream>
using namespace std;
long long climb_stairs_even(int );
long long climb_stairs_odd(int n){
if(n==1) return 1;
if(n==2) return 1;
return climb_stairs_even(n-1)+climb_stairs_even(n-2);
}
long long climb_stairs_even(int n){
if(n==1) return 0;
if(n==2) return 1;
return climb_stairs_odd(n-1)+climb_stairs_odd(n-2);
}
int main(){
cout<<climb_stairs_even(5)<<endl;
return 0;
}
方法二
- 先左后右,必须是左脚开始,右脚结束
- 定义2个函数,左脚上完n个台阶的总方法数为l(int n),右脚上完n个台阶的总方法数为r(int n)
- 出口就是左右脚上完1、2个台阶的方法数。
#include<iostream>
using namespace std;
long long r(int);
long long l(int n){
if(n==1) return 0;
if(n==2) return 1;
return r(n-1)+r(n-2);
}
long long r(int n){
if(n==1) return 1;
if(n==2) return 1;
return l(n-1)+l(n-2);
}
int main(){
cout<<l(5)<<endl;
cout<<l(40)<<endl;
return 0;
}
分零钱
题目
- 有50美分、25美分、10美分、5美分和1美分的硬币,将1美元(100美分)换成零钱,一共有多少种不同方式?
- 找相似性,从总的不同方式开始递归。
- 总的不同方式包括:不含50美分的情况,至少含一个50美分的情况。
- 定义f(m,n)函数,表示钱值m,由n种硬币表示时的不同方式数。
- f(100,5),即100美分,由50美分、25美分、10美分、5美分和1美分一共5种硬币表示的方法数。
- f(100,4),即100美分,由25美分、10美分、5美分和1美分一共4种硬币表示的方法数。
- 出口,当只用1美分硬币表示时的方法数为1,钱数m为负数时的方法数为0。m=0时,即f(0,n)它的意思是钱数为coins[n]时至少含一个coins[n]的方法数,显然此时只有1种方式。
代码
#include<iostream>
using namespace std;
const int coins[]={0,1,5,10,25,50};
int f(int m,int n)
{
if(n==1) return 1;
if(m<0) return 0;
if(m==0) return 1;
return f(m,n-1) + f(m-coins[n],n);
}
int main()
{
cout<<f(100,5);
return 0;
}