C语言经典算法100例(二)

来源:互联网 发布:淘宝买小样靠谱店推荐 编辑:程序博客网 时间:2024/05/21 06:28

11.判断某一年是否是闰年。

[cpp] view plaincopyprint?
  1. //判断某一年份是否是闰年 
  2. int IsLeapYear(int year) 
  3.     return (year % 400 == 0 || (year % 4 == 0) && (year % 100 != 0)); 
//判断某一年份是否是闰年int IsLeapYear(int year){return (year % 400 == 0 || (year % 4 == 0) && (year % 100 != 0));}

运行结果:

12.获得某年、某月的最大天数。

[cpp] view plaincopyprint?
  1. //获得某年、某月的最大天数 
  2. int GetMaxDay(int year,int month) 
  3.     switch(month) 
  4.     { 
  5.     case 1: 
  6.     case 3: 
  7.     case 5: 
  8.     case 7: 
  9.     case 8: 
  10.     case 10: 
  11.     case 12: 
  12.         return 31; 
  13.     case 4: 
  14.     case 6: 
  15.     case 9: 
  16.     case 11: 
  17.         return 30; 
  18.     case 2: 
  19.         return IsLeapYear(year)?29:28;       
  20.     default:return -1; 
  21.     } 
//获得某年、某月的最大天数int GetMaxDay(int year,int month){switch(month){case 1:case 3:case 5:case 7:case 8:case 10:case 12:return 31;case 4:case 6:case 9:case 11:return 30;case 2:return IsLeapYear(year)?29:28;default:return -1;}}

运行结果:

13.输入某年某月某日,判断这一天是这一年的第几天?

[cpp] view plaincopyprint?
  1. //输入某年某月某日,判断这一天是这一年的第几天?  
  2. /* 
  3. 程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊
  4. 情况,闰年且输入月份大于3时需考虑多加一天。
  5. */ 
  6. int GetDays(int year,int month,int day) 
  7.     int sum = 0; 
  8.     int i; 
  9.     for(i = 1; i < month; i++)      //将前几个月天数相加 
  10.         sum += GetMaxDay(year,month); 
  11.     sum = sum + day;  //加上本月的天数,就是总天数 
  12.     return sum; 
//输入某年某月某日,判断这一天是这一年的第几天? /*  程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊 情况,闰年且输入月份大于3时需考虑多加一天。*/int GetDays(int year,int month,int day){int sum = 0;int i;for(i = 1; i < month; i++)      //将前几个月天数相加sum += GetMaxDay(year,month);sum = sum + day;  //加上本月的天数,就是总天数return sum;}


运行结果:

更多关于日期的算法,请参见我的博客《关于日期的常用算方法》(java版)。

14.求一个数的阶乘。

[cpp] view plaincopyprint?
  1. //递归求阶乘 
  2. long factorial(long n) 
  3.     if(n <= 1) 
  4.         return 1; 
  5.     else  
  6.  
  7.         return n * factorial(n-1); 
  8. //非递归求阶乘 
  9. long Factorial(long n) 
  10.     int sum,i; 
  11.     sum = 1; 
  12.     for(i = 1; i <= n; i++) 
  13.         sum *= i; 
  14.     return sum; 
//递归求阶乘long factorial(long n){if(n <= 1)return 1;else return n * factorial(n-1);}//非递归求阶乘long Factorial(long n){int sum,i;sum = 1;for(i = 1; i <= n; i++)sum *= i;return sum;}

运行结果:

这里求得的阶乘只能是较小数的阶乘,想求得200或更大数的阶乘就无能无力了,所以必须通过其他的算法来实现。

关于更大数的阶乘,大家可以参见我的博客《大数阶乘的实现》

15.求两个数的最大公约数和最小公倍数。

[cpp] view plaincopyprint?
  1. //求两个数的最大公约数 
  2. int gcd(int a,int b) 
  3.     int r; 
  4.     if(a < b)        //a < b,则交换两个数 
  5.     { 
  6.         int temp = a; 
  7.         a = b; 
  8.         b = temp; 
  9.     } 
  10.  
  11.     r = a % b; 
  12.     while(r != 0) 
  13.     { 
  14.         a = b; 
  15.         b = r; 
  16.         r = a % b; 
  17.     } 
  18.     return b; 
  19. //求两个数的最小公倍数数 
  20. int lcm(int a,int b) 
  21.     return a*b/gcd(a,b); 
//求两个数的最大公约数int gcd(int a,int b){int r;if(a < b)        //a < b,则交换两个数{int temp = a;a = b;b = temp;}r = a % b;while(r != 0){a = b;b = r;r = a % b;}return b;}//求两个数的最小公倍数数int lcm(int a,int b){return a*b/gcd(a,b);}

运行结果:

16.打印出三位的"水仙花数",所谓"水仙花数"是指一个N位数,其各位数字立方和等于该数。

[cpp] view plaincopyprint?
  1. //打印出三位的"水仙花数",所谓"水仙花数"是指一个N位数,其各位数字立方和等于该数 
  2. void WaterFlowerNumber() 
  3.     int i,j,k,n; 
  4.     printf("Water flower number is:"); 
  5.     for(n = 100; n < 1000; n++) 
  6.     { 
  7.         i = n/100; //分解百位 
  8.         j = n/10 % 10; //分解十位 
  9.         k = n % 10; //分解个位 
  10.         if(i*i*i + j*j*j + k*k*k == n) 
  11.             printf("%-5d\n",n); 
  12.     } 
//打印出三位的"水仙花数",所谓"水仙花数"是指一个N位数,其各位数字立方和等于该数 void WaterFlowerNumber(){int i,j,k,n;printf("Water flower number is:");for(n = 100; n < 1000; n++){i = n/100; //分解百位j = n/10 % 10; //分解十位k = n % 10; //分解个位if(i*i*i + j*j*j + k*k*k == n)printf("%-5d\n",n);}}

运行结果:

大家还可以考虑一下,如何打印21位“水仙花”数? (基本思想和《大数阶乘的实现》及《求任意位数的Pi》的思想相同,即用数组存储)。


17.不依赖第三个变量,实现两个整数交换。

[cpp] view plaincopyprint?
  1. /不依赖第三个变量,实现两个整数交换 
  2. //第一种方法 
  3. void Exchange1(int* a,int* b) 
  4.     *a = *a + *b; 
  5.     *b = *a - *b; 
  6.     *a = *a - *b; 
  7. //第二种方法(用位运算) 
  8. void Exchange2(int* a,int* b) 
  9.     *a = *a ^ *b; 
  10.     *b = *a ^ *b; 
  11.     *a = *a ^ *b; 
/不依赖第三个变量,实现两个整数交换//第一种方法void Exchange1(int* a,int* b){*a = *a + *b;*b = *a - *b;*a = *a - *b;}//第二种方法(用位运算)void Exchange2(int* a,int* b){*a = *a ^ *b;*b = *a ^ *b;*a = *a ^ *b;}

运行结果:


18.将10进制的数转换为2-16进制。

[cpp] view plaincopyprint?
  1. //将10进制数转换为其它进制 
  2. void From10baseTransformTo1_16(int m,int base) 
  3.     char num[] = "0123456789ABCDEF"
  4.     char result[30] = {0}; 
  5.     int len = 0; 
  6.     char temp; 
  7.     int start = 0; 
  8.     int end = len; 
  9.      
  10.     while(m)               //辗转相除,先存正向的余数 
  11.     { 
  12.         result[len++] = num[m%base]; 
  13.         m = m / base; 
  14.     } 
  15.      
  16.     start = 0; 
  17.     end = len-1; 
  18.     while(start < end)  //字符串翻转 
  19.     { 
  20.         temp = result[start]; 
  21.         result[start] = result[end]; 
  22.         result[end] = temp; 
  23.         start++; 
  24.         end--; 
  25.     } 
  26.    
  27.     start = 0; 
  28.     for(start = 0; start < len; start++) 
  29.         printf("%c",result[start]); 
  30.     printf("\n"); 
  31.  
//将10进制数转换为其它进制void From10baseTransformTo1_16(int m,int base){char num[] = "0123456789ABCDEF";char result[30] = {0};int len = 0;char temp;int start = 0;int end = len;while(m)                //辗转相除,先存正向的余数{result[len++] = num[m%base];m = m / base;}    start = 0;end = len-1;while(start < end)   //字符串翻转{temp = result[start];result[start] = result[end];result[end] = temp;start++;end--;}  start = 0;for(start = 0; start < len; start++)    printf("%c",result[start]);printf("\n");}

运行结果:


19.将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。

[cpp] view plaincopyprint?
  1. //将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 
  2. void DivideFactor(int n) 
  3.     int i;  
  4.     printf("\nplease input a number:\n");  
  5.     scanf("%d",&n);  
  6.     printf("%d=",n);  
  7.  
  8.     for(i=2;i<=n;i++)  
  9.     {  
  10.         while(n!=i)  
  11.         {  
  12.             if(n%i==0)  
  13.             {  
  14.                 printf("%d*",i);  
  15.                 n=n/i;  
  16.             }  
  17.             else  
  18.             { 
  19.                 break
  20.             } 
  21.         }  
  22.     }  
  23.     printf("%d",n); 
  24.  
//将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。void DivideFactor(int n){int i; printf("\nplease input a number:\n"); scanf("%d",&n); printf("%d=",n); for(i=2;i<=n;i++) { while(n!=i) { if(n%i==0) { printf("%d*",i);     n=n/i; } else {break;}} } printf("%d",n);}

运行结果:

20.猴子吃桃问题:

猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
程序分析:采取逆向思维的方法,从后往前推断。

[cpp] view plaincopyprint?
  1. void MonkeyEatPeach() 
  2.     int day,x1,x2; 
  3.     day=9; 
  4.     x2=1; 
  5.     while(day>0) 
  6.          {x1=(x2+1)*2;/*第一天的桃子数是第2天桃子数加1后的2倍*/ 
  7.      x2=x1; 
  8.      day--; 
  9.      } 
  10.     printf("the total is %d\n",x1); 
void MonkeyEatPeach(){int day,x1,x2;day=9;x2=1;while(day>0) {x1=(x2+1)*2;/*第一天的桃子数是第2天桃子数加1后的2倍*/ x2=x1; day--; }printf("the total is %d\n",x1);}

运行结果:

原创粉丝点击