各种基本算法实现小结(七)—— 常用算法

来源:互联网 发布:sql 按条件合计 编辑:程序博客网 时间:2024/05/19 18:15

 

转载地址:http://blog.csdn.net/sunboy_2050/article/details/5645837

 

各种基本算法实现小结(七)—— 常用算法

(均已测试通过)

======================================================================

1、判断素数

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <math.h> 
  3. int is_sushu(int n) 
  4.     int i, mid; 
  5.     mid=(int)sqrt(n); 
  6.     for(i=2; i<=mid; i++) 
  7.         if(0 == n%i) 
  8.             return 0; 
  9.     return 1; 
  10. void main() 
  11.     int n; 
  12.      
  13.     printf("Enter a num: "); 
  14.     scanf("%d", &n); 
  15.     if(is_sushu(n)) 
  16.         printf("%d is sushu!/n", n); 
  17.     else 
  18.         printf("%d is not sushu.../n", n); 

运行结果:

   

==========================================================

2、 求2-1000之间的所有素数

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <math.h> 
  3. #define MAX 1000 
  4. int is_sushu(int n) 
  5.     int i, mid; 
  6.     mid=(int)sqrt(n); 
  7.     for(i=2; i<=mid; i++) 
  8.         if(0 == n%i) 
  9.             return 0; 
  10.     return 1; 
  11. void main() 
  12.     int i, count; 
  13.      
  14.     count=0; 
  15.      
  16.     for(i=2; i<=MAX; i++) 
  17.         if(is_sushu(i)) 
  18.         { 
  19.             count++; 
  20.             printf("%5d", i); 
  21.                 if(0 == count%10) 
  22.                     printf("/n"); 
  23.         } 
  24.     printf("/n"); 

运行结果:

==========================================================

3、 验证哥德巴赫猜想

哥德巴赫猜想:任意一个大于等于6的偶数都可以分解为两个素数之和

如: 6 = 3+3;100 = 3+97=11+89; 1000 = 3+997=59+941=。。。

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <math.h> 
  3. #define MAX 1000 
  4. int is_sushu(int n) 
  5.     int i, mid; 
  6.     mid=(int)sqrt(n); 
  7.     for(i=2; i<=mid; i++) 
  8.         if(0 == n%i) 
  9.             return 0; 
  10.     return 1; 
  11. void main() 
  12.     int i, mid, n; 
  13.      
  14.     printf("Enter an even num: "); 
  15.     scanf("%d", &n); 
  16.      
  17.     mid=n/2; 
  18.     for(i=2; i<=mid; i++) 
  19.     { 
  20.         if(is_sushu(i) && is_sushu(n-i)) 
  21.             printf("%d = %d + %d/n", n, i, n-i); 
  22.     } 
  23.      

运行结果:

     

==========================================================

4、 求最大公约数(GCD)和最小公倍数(LCM)

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. void  max_min(int &m,int &n) 
  3.     int tmp; 
  4.     if(m<n) 
  5.     { 
  6.         tmp=m; 
  7.         m=n; 
  8.         n=tmp; 
  9.     } 
  10. int Cal_GCD(int m,int n) 
  11.     int gcd; 
  12.      
  13.     max_min(m, n); 
  14.     gcd=m%n; 
  15.     while(gcd) 
  16.     { 
  17.         m=n; 
  18.         n=gcd; 
  19.         gcd=m%n; 
  20.     } 
  21.     return n; 
  22. void main() 
  23.     int m, n, gcd; 
  24.      
  25.     printf("Enter two num a b: "); 
  26.     scanf("%d %d", &m, &n); 
  27.     gcd=Cal_GCD(m, n); 
  28.     printf("%d and %d GCD: %d/n", m, n, gcd); 
  29.     printf("%d and %d LCM: %d/n", m, n, m*n/gcd); 

运行结果:

==========================================================

5、统计个数(数字)

用随机函数产生100个[0,99]范围内的随机整数,

统计个位上的数字分别为0,1,2,3,4,5,6,7,8,9的数的个数并打印出来

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <time.h> 
  4. #include <string.h> 
  5. #define MAX 101 
  6. void input(int num[]) 
  7.     int i; 
  8.     srand((unsigned)time(NULL)); 
  9.     for(i=1; i<MAX; i++) 
  10.         num[i]=rand()%100; 
  11. void output(int num[]) 
  12.     int i; 
  13.     for(i=1; i<MAX; i++) 
  14.     { 
  15.         printf("%5d", num[i]); 
  16.         if(0==i%10) 
  17.             printf("/n"); 
  18.     } 
  19.     printf("/n"); 
  20. void cal_num(int num[],int count[]) 
  21.     int i, mod; 
  22.      
  23.     for(i=1; i<MAX; i++) 
  24.     { 
  25.         mod=num[i]%10; 
  26.         count[mod]++; 
  27.     } 
  28. void main() 
  29.     int num[MAX]; 
  30.     int i, count[10]; 
  31.      
  32.     memset(count, 0, 10*sizeof(int));/* initial count[] to 0 */ 
  33.     input(num); 
  34.     printf("100 num:/n"); 
  35.     output(num); 
  36.      
  37.     cal_num(num, count); 
  38.     for(i=0; i<10; i++) 
  39.         printf("%d: %d/n", i, count[i]);     

运行结果:

==========================================================

6、统计个数(数字、字符、其它字符)

输入一行字符,统计其中有多少个数字、字符和其它字符

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <string.h> 
  3. #define MAX 1024 
  4. void cal_num(char *str,int count[]) 
  5.     char *pstr; 
  6.     pstr=str; 
  7.     while(*pstr) /* *pstr != 0 */ 
  8.     { 
  9.         if(*pstr>='0' && *pstr<='9'
  10.             count[0]++; 
  11.         else if((*pstr>='a' && *pstr<='z') || (*pstr>='A' && *pstr<='Z')) 
  12.             count[1]++; 
  13.         else 
  14.             count[2]++; 
  15.          
  16.         pstr++; 
  17.     } 
  18. void main() 
  19.     char str[MAX]; 
  20.     int i, count[3];  /* 0->num; 1->char; 2->others */ 
  21.     memset(count, 0, 3*sizeof(int)); 
  22.      
  23.     printf("Enter a string: "); 
  24.     scanf("%s", str); 
  25.     cal_num(str, count); 
  26.     for(i=0; i<3; i++) 
  27.     { 
  28.         switch(i) 
  29.         { 
  30.             case 0: 
  31.                 printf("num: %d/n", count[i]); 
  32.                 break
  33.             case 1: 
  34.                 printf("char: %d/n", count[i]); 
  35.                 break
  36.             case 2: 
  37.                 printf("other: %d/n", count[i]); 
  38.                 break
  39.         } 
  40.     } 

运行结果:

==========================================================

7、 数制转换(递归实现)

本算法仅实现了基数为2-16的数制转换

如果大家希望扩展范围,仅需要对基数表示字符case 进行扩展即可,如G、H、I ...

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. int flag=1; /* check: n/d == 0 */ 
  3. void trans_num(int n,int d) 
  4.     int mod; 
  5.     mod=n%d; 
  6.     n=n/d; 
  7.     while(flag && n) 
  8.         trans_num(n,d); 
  9.     flag=0; 
  10.     switch(mod) 
  11.     { 
  12.         case 10: 
  13.             printf("A"); 
  14.             break
  15.         case 11: 
  16.             printf("B"); 
  17.             break
  18.         case 12: 
  19.             printf("C"); 
  20.             break
  21.         case 13: 
  22.             printf("D"); 
  23.             break
  24.         case 14: 
  25.             printf("E"); 
  26.             break
  27.         case 15: 
  28.             printf("F"); 
  29.             break
  30.         default
  31.             printf("%d", mod);   
  32.     } 
  33.          
  34. void main() 
  35.     int n, d; 
  36.     printf("Enter n d: "); 
  37.     scanf("%d %d", &n, &d); 
  38.      
  39.     trans_num(n, d); 
  40.     printf("/n");    

运行结果:

       

算法改进

数制直接转为字符输出,扩展支持16进制以上的数制转换

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. int flag=1; /* check: n/d == 0 */ 
  3. void trans_num(int n,int d) 
  4.     int mod; 
  5.     mod=n%d; 
  6.     n=n/d; 
  7.     while(flag && n) 
  8.         trans_num(n,d); 
  9.     flag=0; 
  10.     if(mod>=10) 
  11.         mod=mod-10+65;  /* convert to char */ 
  12.     else 
  13.         mod=mod+48; 
  14.     printf("%c", mod);  /* print char (%c) */    
  15. void main() 
  16.     int n, d; 
  17.     printf("Enter n d: "); 
  18.     scanf("%d %d", &n, &d); 
  19.      
  20.     trans_num(n, d); 
  21.     printf("/n");    

运行结果(扩展进制):

             

100 = 4*24+4            1000=1*24*24+17*24+16  10000=17*24*24+8*24+16        1000=27*36+28

==========================================================

8、 数制转换(栈实现)


核心思想和递归实现类似,都是压栈的原理,实现较简单,请自己尝试实现

==========================================================

9、 水仙花数

水仙花数简述: 水仙花数是指一个 n 位数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。

如:153=1^3+5^3+3^3(3位数);1634=1^4+6^4+3^4+4^4(4位数);54748=5^5+4^5+7^5+4^5+8^5(5位数)

判断任一3位数,是否为水仙花数

测试环境:GCC

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. main() 
  3.     int b, s, g, n, sum; 
  4.     scanf("%d", &n); 
  5.     b=n/100; 
  6.     s=n/10%10; 
  7.     g=n%10; 
  8.     sum=b*b*b+s*s*s+g*g*g; 
  9.     if(sum==n) 
  10.         printf("Yes/n"); 
  11.     else 
  12.         printf("No/n"); 

运行结果(Redhat Linux):

================================================

求4位数的水仙花数(1000<=X<=9999)

测试环境:VC 6.0 (C)

 

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. int main() 
  3.     int i,j,k,l,m,n; 
  4.     for(i=1; i<=9; i++) 
  5.         for(j=0; j<=9; j++) 
  6.             for(k=0; k<=9; k++) 
  7.                 for(l=0; l<=9; l++) 
  8.                     if((i*1000+j*100+k*10+l)==i*i*i*i+j*j*j*j+k*k*k*k+l*l*l*l) 
  9.                         printf("%d%d%d%d=%d^4+%d^4+%d^4*%d^4/n", i, j, k, l, i, j, k, l); 
  10.     return 0; 

运行结果:

================================================

思考:如果求得高精度大数的水仙花数,如8位、18位、28位的水仙花数(需考虑计算机精度,可采用数组或指针实现,大数计算)

==========================================================

10、 大数计算

大数运算:参加的值和计算结果通常是以上百位数,上千位数以及更大长度之间的整数运算,早已超出了计算机能够表示数值的精度范围(2^32=4294967296或2^64=18446744073709551616)即64位机最大也才20位,因此需要想出其它的办法计算大数。

求任意两整数之和(1000位以内)

测试环境:VC 6.0 (C)

[cpp:showcolumns] view plaincopyprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <stdio.h> 
  2. #include <string.h> 
  3. #define MAX 1000 /* precision */ 
  4. void input(char ch[]) 
  5.     scanf("%s", ch); 
  6. void add(char ch1[],char ch2[], char ch3[]) 
  7.     int len1, len2, len3, maxlen; 
  8.     int sum, flag; 
  9.     len1=strlen(ch1); 
  10.     len2=strlen(ch2); 
  11.     len3=maxlen=len1 >= len2 ? len1 : len2; 
  12.     flag=0; /* jin wei */ 
  13.      
  14.     while(len1>=1 && len2>=1) 
  15.     { 
  16.         sum=ch1[len1-1]-'0' + ch2[len2-1]-'0' + flag;/* char -> int to calculate sum */ 
  17.         flag=0; 
  18.          
  19.         if(sum>=10) 
  20.         { 
  21.             sum-=10; 
  22.             flag=1; 
  23.         } 
  24.         ch3[maxlen-1]=sum + '0'
  25.         len1--; 
  26.         len2--; 
  27.         maxlen--; 
  28.     } 
  29.     while(len1>=1) /* if num1[] is longer or maxer */ 
  30.     { 
  31.         sum=ch1[len1-1]-'0' + flag; 
  32.         flag=0; 
  33.          
  34.         if(sum>=10) 
  35.         { 
  36.             sum-=10; 
  37.             flag=1; 
  38.         } 
  39.         ch3[maxlen-1]=sum + '0'
  40.         len1--; 
  41.         maxlen--; 
  42.     } 
  43.      
  44.     while(len2>=1) /* if num2[] is longer or maxer */ 
  45.     { 
  46.         sum=ch2[len2-1]-'0' + flag; 
  47.         flag=0; 
  48.          
  49.         if(sum>=10) 
  50.         { 
  51.             sum-=10; 
  52.             flag=1; 
  53.         } 
  54.         ch3[maxlen-1]=sum + '0'
  55.         len2--; 
  56.         maxlen--; 
  57.     } 
  58.     if(flag != 0) /* if flag, then print gaowei(jinwei) */ 
  59.         printf("%d", flag); 
  60.     for(int i=0; i<len3; i++)  
  61.         printf("%c", ch3[i]);    
  62.     printf("/n"); 
  63. int main() 
  64.     char ch1[MAX], ch2[MAX], ch3[MAX+1]; 
  65.     memset(ch3, '0', sizeof(ch3)); 
  66.     input(ch1); 
  67.     input(ch2); 
  68.     add(ch1, ch2, ch3); 
  69.     return 0; 

运行结果:

   

思考:请大家自己设计实现更复杂的大数减法、乘法、除法,求余、求幂、求最小公倍数等大数运算(提示:可用数组或链表)