#include
#include
#include
int add_up(int n){
if(n==1){
return 1;
}
return n+add_up(n-1);
}
void main()
{
int n=5;
printf("%d\n",add_up(n));
return;
}
递归方法:
int funN(int N)
{
if (1>=N)
{
return 1;
}
else
{
return N*funN(N-1);
}
}
非递归方法:
int funN(int N)
{
int i,val = 1;
if (N<=0)
{
return 0;
}
for(i=1;i<=N;i++)
{
val*=i;
}
return val;
}
质数又称素数。一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数;
定义判别法:
#include
#include
int isprime(int val)
{
int n = 2;
for(n; n
非要写成递归也可以:
#include
#include
#include
//1是 0不是
int prime_orNot(int n,int helper){
if(helper>=n){
return 1;
}
if(n<=1){
return -1;
}
if(n%helper==0){
return 0;
}
if(n>=2){
return prime_orNot(n,helper+1);
}
}
int main(){
for(int i = 2;i<=100;i++){
if(prime_orNot(i,2)==1){
printf("%d\n",i);
}
}
return 0;
}
#include
#include
#include
void to_binary(int num){
int bin=num%2;
if(num>=2){
to_binary(num/2);
}
printf("%c",bin+'0');
}
int main(){
int num = 10;
to_binary(num);
system("pause");
return 0;
}
C中单个数字到字符的转换,加‘0’。
#include
#include
#include
//正整数顺序输出
void print_ten_to_two_order(int n){
if(n>=10){
print_ten_to_two_order(n/10);
}
printf("%c\n",n%10+'0');
}
//正整数逆序输出
void print_ten_to_two_reverse(int n){
if(n>0){
printf("%c\n",n%10+'0');
print_ten_to_two_reverse(n/10);
}
}
int main(){
print_ten_to_two_order(1234560);
print_ten_to_two_reverse(1234560);
return 0;
}
#include
#include
#include
int sum_up(int n){
if(n/10==0){
return n;
}
return sum_up(n%10)+sum_up(n/10);
}
void main()
{
int n=123456;
printf("%d\n",sum_up(n));
return;
}
#include
#include
#include
int pow_fun(int n, int k){
if(k==1){
return n;
}
return n*pow_fun(n,k-1);
}
void main()
{
int n=3,k=3;
printf("%d\n",pow_fun(n,k));
return;
}
也称最大公因子,指两个或多个整数共有约数中最大的一个。
可以采用更相减损法,也叫更相减损术,是出自中国古代数学专著《九章算术》的一种求公约数的算法。
具体求法是: 以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。 这个相等的值就是最大公约数。
#include
#include
#include
int Max_common_divisor(int m, int n){
if(m<=1||n<=1){
return 1;
}
if(m>n){
return Max_common_divisor(m-n,n);
}
if(m
另一种实现:
#include
#include
#include
int gbs(int n,int m)
{
if(n%m){
return gbs(m,n%m);
}
else{
return m;
}
}
void main()
{
int m=8,n=12;
printf("%d\n",gbs(m,n));
return;
}
两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
a,b的最小公倍数 = a×b/(a,b的最大公约数)
void funN(char *s)
{
if (*s != '\0')
{
funN(s+1);
printf("%c",*s);
}
}
例如对于{'a','b','c','\0','d','e'},N=2、3时,长度是2、3,N=5、6时,长度是3。 思路: 字符串折半递归。
#include
#include
#include
int strlen_length(char* str,int N){
int length; //C中变量定义要放在最前
if(*str=='\0' || N==0){
return 0;
}
if(N==1)
{
return 1;
}
length = strlen_length(str,N/2);
if(length
#include
#include
#include
int strlen(char* str){
if(*str=='\0'){
return 0;
}
return(1+strlen(str+1));
}
int main()
{
char *str="1234560";
printf("%d",strlen(str));
system("pause");
}
0和单个字符也认为是回文。
#include
#include
#include
// 0 不是回文 1是回文
int huiwen(char *str, int length)
{
if(*str=='\0'||length<=1){
return 1;
}
if(*str!=str[length-1]){
return 0;
}
else{
return huiwen(str+1,length-2);
}
}
int main(){
char str[]="aaabcde66edcbaaa";
printf("%d\n",huiwen(str,strlen(str)));
system("pause");
return 0;
}
又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。 斐波那契数列中F(n)=F(n-1)+F(n-2)(n>=3)。
递归实现,判断斐波那契数列中第n位的值。
#include
#include
long bofei(int val)
{
if(0>=val){
return 0;
}
if(1==val){
return 1;
}
if(2==val){
return 2;
}
return bofei(val-1)+bofei(val-2);
}
int main()
{
int ss = 10;
printf("%ld",bofei(ss));
return 0;
}
非递归实现,判断斐波那契数列中第n位的值:
#include
#include
long bofei(int val)
{
long arr[100];
arr[0]=0;
arr[1]=1;
arr[2]=2;
for(int i=3; i<=val;i++){
arr[i]=arr[i-1]+arr[i-2];
}
return arr[val];
}
int main()
{
int ss = 50;
printf("%ld",bofei(ss));
return 0;
}
A(from)、B(helper)、C(to)
1. n个盘从A移动到C,需要借助B,先把n-1个盘移动到B(这个最终呈现出来的效果,至于过程怎么实现的不管),再把第n的盘移动到C;
2. 再把B上的n-2个盘借助A,移动到A上,把第n-1的盘移动到C; 如此反复;
void hannoi(int n, char from, char helper, char to){
if(n>1){
hannoi(n-1,from,to,helper);
print_line("take"+n+"from"+from+"to"+to);
hannoi(n-1,helper,from,to)
}
else{
print_line("take"+n+"from"+from+"to"+to);)
}
}
思路:1. 先确定首位,首位有n种情况; 2. 确定首位之后,剩下的n-1位再全排列; 3. 全排列次数f(n)=n*f(n-1);
递归求法:
#include
#include
#include
// 不重复字符串全排列数量
int permutation_num(int length)
{
if(length<=1){
return 1;
}
else{
return length*permutation_num(length-1);
}
}
void main()
{
int n=6;
printf("%d\n",permutation_num(n));
return;
}
非递归求法:
#include
#include
#include
int permutation_num(int n){
int list_[n]; //list_[0]~list_[n-1]对应1~n位字符全排列的排列数
list_[0] = 1;
for(int i=1;i
如abc,全排列为abc、acb、bac、bca、cab和cba。
思路: 第一步是确定第一个位置的字符,就是第一个位置与后边的所有字符进行交换。这一共有n中情况,所以递归函数里涉及一个n次循环。
第二步,就是对除了第一个位置的后边所有位置的字符进行相同处理;直至剩下一个字符,打印;这里是递归函数里循环体。
#include
#include
#include
void permutation_num(char* start, char* move){
if(*move=='\0')
{
printf("%s\n",start);
return;
}
else
{
for(char* begin=move;*begin!='\0';begin++)
{
char temp = *begin;
*begin = *move;
*move = temp;
permutation_num(start,move+1);
temp = *begin;
*begin = *move;
*move = temp;
}
}
}
void main()
{
char str[] = "abc";
permutation_num(str,str);
return;
}
以上递归没有考虑去重,去重版本:
#include
#include
#include
int swap_(char * begin, char* end){
for(char * start=begin; start!=end;start++){
if(*start==*end){
return 0;
}
}
return 1;
}
void permutation_num(char* start, char* move){
if(*move=='\0')
{
printf("%s\n",start);
return;
}
else
{
for(char* begin=move;*begin!='\0';begin++)
{
if(swap_(move,begin)){
char temp = *begin;
*begin = *move;
*move = temp;
permutation_num(start,move+1);
temp = *begin;
*begin = *move;
*move = temp;
}
}
}
}
void main()
{
char str[] = "acc";
permutation_num(str,str);
return;
}
C中没有string字符串指针,需要使用二级指针实现。
#include
#include
#include
int repetition(char** start){
if(*(start+1)=='\0'||*(start)=='\0') //如果只有一个元素或为空
{
return 0;
}
else
{
for(char** begin=start+1;*begin!='\0';begin++) //逐个比对
{
if(*start == *begin){
return 1;
}
}
repetition(start+1);
}
}
void main()
{
char *str[]= {"aa","bb","cc","aa"};
printf("%d\n",repetition(str));
return;
}
1. 原地反转
2. 自己实现strlen功能
#include
#include
#include
int strlen_(char *str){
if(*str=='\0'){
return 0;
}
return 1+strlen_(str+1);
}
void reverse(char* p){
if(strlen_(p)<=1||*p=='\0'){
return;
}
else{
int length = strlen_(p);
char temp = *p;
*p = *(p+length-1);
*(p+length-1) = '\0';
reverse(p+1);
*(p+length-1) = temp;
}
}
void main()
{
char str[]="abcedfgd";
reverse(str);
printf("%s\n",str);
return;
}
#include
#include
#include
char* reverse(char* p){
char* str=(char*)malloc(10);
int length = strlen(p);
for(int i=0;i0;num = num/10){
*p = (num%10)+'0';
p=p+1;
}
*p='\0';
return reverse(str); //字符反转
}
void main()
{
int num=123456;
printf("%s\n",itoa(num));
return;
}
相关:
1. 自己实现strlen
2. 正整数转字符串
3. 字符串反转
4. 字符串插入
#include
#include
#include
int strlen_(char *str){
if(*str=='\0'){
return 0;
}
return 1+strlen_(str+1);
}
void reverse(char* p){
if(strlen_(p)<=1||*p=='\0'){
return;
}
else{
int length = strlen_(p);
char temp = *p;
*p = *(p+length-1);
*(p+length-1) = '\0';
reverse(p+1);
*(p+length-1) = temp;
}
}
char* itoa(int num)
{
char* str = (char*)malloc(10);
char* p = str;
for(num;num>0;num = num/10){
*p = (num%10)+'0';
p=p+1;
}
*p='\0';
reverse(str); //字符反转
return str;
}
char * insert_douhao(char* str){
int length = strlen_(str);
char* p =(char*)malloc(length+abs(length-1)/3);
for(int i=0;i
在递归里,对于指针p,一般忌讳使用 p++, 通常使用p+1 。 p++之后指针p的值已经变了,不再指向初始地址,而p+1只是传入指针p之后的那个地址,指针p本身并没有改变。
NULL、'\0'、0
NULL用于指针或者对象的置空,表示一个不指向任何对象的空指针。
'\0'用于字符串的结束标志。
0也可以作为字符串的结尾标志,如下表述也是没有问题的:
char str[4] = { '1', '2', '3', 0 }; //这里strlen(str)的值是3
C中单个数字到字符的转换,加‘0’。