几个经典基础算法题目

练习1,判断是否为素数:

  1. // ConsoleAppIsPrime1.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *函数功能:判断一个输入的数是否为素数 
  5. *函数原形:bool Prime( int x ) 
  6. *参数:int x:将要判断的数 
  7. *返回值:bool型变量,判断是否是素数 
  8. *备注:需要包含头文件<math.h> 
  9. *日期:2014/11/25 
  10. *原创:否 
  11. *作者:EbowTang 
  12. *Email:tangyibiao520@163.com 
  13. */  
  14.   
  15. #include "stdafx.h"  
  16. #include "math.h"  
  17. #include "iostream"  
  18.   
  19. using namespace std;  
  20.   
  21. bool Prime( int x );  
  22.   
  23. int _tmain(int argc, _TCHAR* argv[])  
  24. {  
  25.     bool flag;  
  26.     int a;  
  27.   
  28.     while (true)  
  29.     {  
  30.         cout<<"Please enter a number:";  
  31.         cin>>a;  
  32.         flag=Prime(a);  
  33.         if (flag==true)  
  34.             cout<<"Prime!!!"<<endl;  
  35.         else  
  36.             cout<<"Not Prime!";  
  37.     }  
  38.   
  39.     system("pasue");  
  40.     return 0;  
  41. }  
  42.   
  43. /*原理:将输入的x与2到sqrt(x)整除一遍,若其中任意一个能整除则x不是素数*/  
  44. bool Prime( int x )  
  45. {  
  46.     x=abs( x );  
  47.     if ( x < 1 )  
  48.         return false;  
  49.     for (int i = 2; i <= int( sqrt( float( x ))) ; i++ )  
  50.     {  
  51.         if ( x % i==0 )//一旦可以整除立马返回他不是素数  
  52.             return false;  
  53.     }  
  54.     return true;  
  55. }  


练习2,指定范围内的素数:

  1. // ConsoleAppIsPrime.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *函数功能:判断指定范围内素数个数 
  5. *函数原形:int Primes( int n ,int m ) 
  6. *参数: 
  7. int n:请输入想要确认的素数范围下限 
  8. int m:请输入想要确认的素数范围上限 
  9. *返回值:n到m范围内素数的个数 
  10. *备注: 
  11. *日期:2014/11/25 
  12. *原创:是 
  13. *作者:EbowTang 
  14. *Email:tangyibiao520@163.com 
  15. */  
  16. #include "stdafx.h"  
  17. #include "iostream"  
  18. #include "math.h"  
  19.   
  20. using namespace std;  
  21.   
  22.   
  23. int Primes( int n ,int m );  
  24. bool Prime( int x );  
  25.   
  26. int _tmain(int argc, _TCHAR* argv[])  
  27. {  
  28.     int countprimes=0;  
  29.     int a=0;  
  30.     int b=0;   
  31.       
  32.     while (true)  
  33.     {  
  34.         cout<<"请输入想要确认的素数范围上限:";  
  35.         cin>> a ;  
  36.         cout<<"请输入想要确认的素数范围下限:";  
  37.         cin>> b;  
  38.         countprimes=Primes(a,b);  
  39.         cout<<"在 "<< a <<"到 "<< b <<"之间的素数个数为: "<< countprimes<<endl;  
  40.     }  
  41.   
  42.     system("pause");  
  43.     return 0;  
  44. }  
  45.   
  46.   
  47.   
  48. bool Prime( int x )//判断素数  
  49. {  
  50.     x=abs( x );  
  51.     if ( x < 1 )  
  52.         return false;  
  53.     for (int i = 2; i <= int( sqrt( float( x ))) ; i++ )  
  54.             if ( x % i==0 )  
  55.                 return false;  
  56.     return true;  
  57.   
  58. }  
  59.   
  60. int Primes( int n ,int m )//统计素数  
  61. {  
  62.     int count=0;  
  63.     bool flag=false;  
  64.     for (; n <= m ; n++)  
  65.     {  
  66.         flag=Prime( n );  
  67.         if (flag==true)  
  68.             count++;  
  69.     }  
  70.     return count;  
  71. }  


练习3,某整数是否为2的次幂:

  1. /* 
  2. *函数功能:判断一个整数是否为2的次幂 
  3. *函数原形:bool IsTwoN(int n); 
  4. *参数:int n,要判断的整数 
  5. *返回值:bool型变量,表征是与否 
  6. *时间复杂度:O(1) 
  7. *备注:无 
  8. *日期:2014/11/23 
  9. *原创:否 
  10. *作者:EbowTang 
  11. *Email:tangyibiao520@163.com 
  12. */  
  13. #include "stdafx.h"  
  14. #include "iostream"  
  15. #include "math.h"  
  16. using namespace std;  
  17.   
  18. bool IsTwoN(int n);  
  19.   
  20. int _tmain(int argc, _TCHAR* argv[])  
  21. {     
  22.     while(1)  
  23.     {  
  24.         bool flag;  
  25.         int m;  
  26.         cout<<"请输入一个整数:"<<endl;  
  27.         cin>>m;  
  28.         flag=IsTwoN(m);  
  29.         if (flag==true)  
  30.             cout<<m<<"是2的次幂,恭喜你!"<<endl<<endl;  
  31.         else  
  32.             cout<<m<<"不是2的次幂"<<endl<<endl;    
  33.     }         
  34.     return 0;  
  35. }  
  36.   
  37. bool IsTwoN(int n)  
  38. {     
  39.     //若是,必定与其自身减1后的数相“与”为假,比如8,1000&0111=0000,  
  40.     //if(n>0&&((n&(n-1))==0))/*第一种方法*/  
  41.     //如果n==2的log以2为底数的n对数的pow函数后,则是  
  42.     if (n==pow(2,(int)(log10(n)/log10(2.))))/*第二种方法*/  
  43.         return true;  
  44.     else  
  45.         return false;  
  46. }  


练习4,整数的二进制数中1的个数:

  1. /* 
  2. *函数功能:求取整数对应二进制数中1的个数 
  3. *函数原形:int Count(int z); 
  4. *参数:int z,要计算的整数 
  5. *返回值:返回整数对应二进制数中1的个数 
  6. *时间复杂度:O(1) 
  7. *备注:无 
  8. *日期:2014/11/23 
  9. *原创:否 
  10. *作者:EbowTang 
  11. *Email:tangyibiao520@163.com 
  12. */  
  13. #include "stdafx.h"  
  14. #include "iostream"  
  15. using namespace std;  
  16.   
  17. int Count(int z);  
  18. int main()  
  19. {  
  20.     int number;  
  21.     int z;  
  22.     char asn='n';  
  23.     do   
  24.     {  
  25.     cout<<"请输入一个整数:"<<endl;  
  26.     cin>>z;  
  27.     number=Count(z);  
  28.     cout<<"该整数对应二进制数1的个数为:"<<endl;  
  29.     cout<<number<<endl;  
  30.     cout<<"是否继续?(y/n)";  
  31.     cin>>asn;  
  32.     } while (asn=='y');  
  33.     return 0;  
  34. }  
  35.   
  36. int Count(int v)  
  37. {  
  38.     int num=0;  
  39.     while (v)  
  40.     {  
  41.         //第一种算法:复杂度较低  
  42.         //  num+=v & 0x01;  
  43.         //  v >>=1;  
  44.         //第二种算法:  
  45.         //  v&=(v-1);  
  46.         //  num++;  
  47.         /*第三种算法:算法复杂度较高*/  
  48.         if(v%2==1)  
  49.             num++;  
  50.         v=v/2;  
  51.     }  
  52.     return num;  
  53. }  

练习5,统计指定数据出现次数:

  1. // ConsoleAppDigitCount.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /*  
  4. *问题描述:用随机函数生成100个在100到999之间的整数,设计程序统计这些三位数中十位是分别是0-9出现次数  
  5. *问题示例:无  
  6. *函数功能:统计三位数中十位数0-9出现的次数  
  7. *函数原形:void DigitCount(int num[], int count[])  
  8. *参数:int num[], 欲统计的数组,int count[]存储统计结果  
  9. *返回值: 无      
  10. *时间复杂度:O(n)  
  11. *备注:无  
  12. *日期:2014/12/31  
  13. *算法描述:  
  14. */  
  15. #include "stdafx.h"  
  16. #include "iostream"  
  17. #include <stdlib.h>  
  18. #include <time.h>  
  19. #include <string.h>  
  20. using namespace std;  
  21. #define MAX 100  
  22. using namespace std;  
  23. /*  
  24. *函数功能:生成100到999的随机整数数  
  25. *函数原形:void RandNumIn(int num[])  
  26. *参数:int num[],用于存储随机整数  
  27. *返回值:无  
  28. */  
  29. void RandNumIn(int num[])  
  30. {  
  31.     srand((unsigned)time(NULL));  //设置随机种子  
  32.     for( int i=0; i<MAX; i++)  
  33.         num[i]=100+rand()%900;       //生成100到999的随机整数数  
  34. }  
  35. /*  
  36. *函数功能:输出生成的100个随机整数  
  37. *函数原形:void output(int num[])  
  38. *参数:int num[],即将输出的整数  
  39. *返回值:无                                                          
  40. */  
  41. void RandNumOut(int num[])  
  42. {  
  43.     int count=0;  
  44.     for( int i=0; i<MAX; i++)  
  45.     {  
  46.         cout<<num[i]<<"  ";  
  47.         count++;  
  48.         if(0==count%10)//每个10个数字就换行  
  49.             cout<<endl;  
  50.     }  
  51.     cout<<endl;  
  52. }  
  53.   
  54. /*  
  55. *函数功能:统计三位数中十位数0-9出现的次数  
  56. *函数原形:void DigitCount(int num[], int count[])  
  57. *参数:int num[], 欲统计的数组,int count[]存储统计结果  
  58. *返回值: 无                                                         
  59. */  
  60. void DigitCount(int num[], int count[])  
  61. {  
  62.     int mod;  
  63.     for(int i=0; i<MAX; i++)  
  64.     {  
  65.         mod=num[i]/10%10;         //得到十位数字  
  66.         count[mod]++;  
  67.     }  
  68.       
  69. }  
  70.   
  71. int _tmain(int argc, _TCHAR* argv[])  
  72. {  
  73.     int num[MAX], count[10];  
  74.     memset(count, 0, 10*sizeof(int)); /* 初始化统计数组 */  
  75.     memset(num, 0, 100*sizeof(int)); /* 初始化随机数组 */  
  76.       
  77.     cout<<"100个随机整数如下:"<<endl;  
  78.     RandNumIn(num);//生成100个随机数  
  79.     RandNumOut(num);//输出100个随机数  
  80.     DigitCount(num, count);//统计十位数的出现个数  
  81.     for(int i=0; i<10; i++)  
  82.         cout<<"十位数"<<i<<":"<<count[i]<<endl;    
  83.     cout<<endl;  
  84.       
  85.     cout<<"其中十位数为0的数为:"<<endl;  
  86.     for (int i=0;i<MAX;i++)  
  87.     {  
  88.         if (num[i]/10%10==0)  
  89.         {  
  90.             cout<<num[i]<<" ";  
  91.         }  
  92.     }  
  93.     cout<<endl;  
  94.     system("pause");  
  95.     return 0;  
  96. }  




练习6,进制的转换:

  1. // ConsoleAppHexadecimalTrans.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *问题描述:将十进制转换成二进制或者八进制,16进制 
  5. *问题示例:输入50 2,输出110010 
  6. *函数功能: 
  7. *函数原形:void HexadecimalTrans(int n, int d) 
  8. *参数:int n,十进制整数 int d,进制数 
  9. *返回值:无 
  10. *时间复杂度: 
  11. *备注:无 
  12. *日期:2014/11/30 
  13. *算法描述: 
  14. */  
  15. #include "stdafx.h"  
  16. #include <iostream>  
  17. using namespace std;  
  18.   
  19. int flag=1;  
  20.   
  21. void HexadecimalTrans(int n, int d)  
  22. {  
  23.     int mod;  
  24.     mod=n%d;                       //n表示数字,d表示进制  
  25.     n=n/d;  
  26.     while(flag && n)               //辗转相除  
  27.         HexadecimalTrans(n,d);  
  28.     switch(mod)                     
  29.     {  
  30.         case 10:  
  31.             cout<<"A";  
  32.             break;  
  33.         case 11:  
  34.             cout<<"B";                
  35.             break;  
  36.         case 12:  
  37.             cout<<"C";  
  38.             break;  
  39.         case 13:  
  40.             cout<<"D";  
  41.             break;  
  42.         case 14:  
  43.             cout<<"E";  
  44.             break;  
  45.         case 15:  
  46.             cout<<"F";  
  47.             break;  
  48.         default:  
  49.             cout<<mod;    //二进制和八进制均在这里输出,mod保存了辗转相除的每次结果  
  50.     }  
  51.     flag=0;  
  52. }  
  53.   
  54. int _tmain(int argc, _TCHAR* argv[])  
  55. {  
  56.     int n, d;  
  57.     cout<<"输入十进制数字:"<<endl;  
  58.     cin>>n;  
  59.     cout<<"请输入将要进行的进制转换(2,8,16):"<<endl;  
  60.     cin>>d;  
  61.     HexadecimalTrans(n,d);       //调用转换函数  
  62.     cout<<endl;  
  63.     system("pause");  
  64.     return 0;  
  65. }  


练习7,查找指定数据的位置(暴力搜索):

  1. // ConsoleAppSpecifiedSearch.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *问题描述:暴力搜索遍历查找,从100个随机函数中(100-999)查找指定数字的位置 
  5. *问题示例: 
  6. *函数功能:查找指定的数 
  7. *函数原形:int FindNum(int num[], int x) 
  8. *参数:int num[],要查找的数组, int x,要查找的数 
  9. *返回值:数字的位置 
  10. *时间复杂度:O() 
  11. *备注:无 
  12. *日期:2014/7/30 
  13. *算法描述: 
  14. */  
  15. #include "stdafx.h"  
  16. #include <iostream>  
  17. #include <stdlib.h>  
  18. #include <time.h>  
  19.   
  20. using namespace std;  
  21.   
  22. #define MAX 100  
  23. /* 
  24. *函数功能:产生指定的随机数 
  25. *函数原形:void RandNumIn(int num[]) 
  26. *参数:int num[],产生的随机数保存到数组num中 
  27. *返回值:无 
  28. */  
  29. void RandNumIn(int num[])  
  30. {  
  31.     int i;  
  32.   
  33.     srand((unsigned)time(NULL));       //得到随机种子  
  34.     for(i=0; i<MAX; i++)  
  35.         num[i]=100+rand()%900;             //生成100--999以内的随机三位整数  
  36. }  
  37. /* 
  38. *函数功能:输出产生的随机数 
  39. *函数原形:void RandNumOut(int num[]) 
  40. *参数:int num[],将要输出的数组 
  41. *返回值:无 
  42. */  
  43. void RandNumOut(int num[])  
  44. {  
  45.     int count=0;  
  46.     for(int i=0; i<MAX; i++)  
  47.     {  
  48.         cout<<num[i]<<"  ";  
  49.         count++;  
  50.         if(0==count%10)  
  51.             cout<<endl;  
  52.     }  
  53. }  
  54.   
  55. /* 
  56. *函数功能:查找指定的数 
  57. *函数原形:int FindNum(int num[], int x) 
  58. *参数:int num[],要查找的数组, int x,要查找的数 
  59. *返回值:数字的位置 
  60. */  
  61. int FindNum(int num[], int x)  
  62. {  
  63.     for(int i=0; i<MAX; i++)  
  64.         if(x == num[i])        //遍历查找指定数字的位置  
  65.             return i;  
  66.     return 0;  
  67. }  
  68.   
  69. int _tmain(int argc, _TCHAR* argv[])  
  70. {  
  71.     int x, pos, num[MAX];        //设置存储数组  
  72.     RandNumIn(num);  
  73.   
  74.     cout<<"随机生成的数字: "<<endl;  
  75.     RandNumOut(num);  
  76.   
  77.     cout<<"请输入要查找的三位整数"<<endl;  
  78.     cin>>x;  
  79.     pos=FindNum(num, x);           //调用查找函数  
  80.   
  81.     if(pos)  
  82.         cout<<"太好了!"<<x<< "的位置在: "<< pos<<endl;  
  83.     else  
  84.         cout<<"抱歉!"<<x<< "并未找到! "<<endl;  
  85.     system("pause");  
  86.     return 0;  
  87. }  


练习8,二分法查找指定数据位置:

  1. // ConsoleAppSpecifiedSearch.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *问题描述:二分法遍历查找,从100个随机函数中(100-999)查找指定数字的位置 
  5. *问题示例: 
  6. *函数功能:二分查找法查找指定的数 
  7. *函数原形:int SpecialFindNum(int num[], int x, int low, int high) 
  8. *参数: 
  9. int num[],要查找的数组,  
  10. int x,要查找的数 
  11. int low, 查找的起始位置 
  12. int high,查找的末端位置 
  13. *返回值:数字的位置 
  14. *时间复杂度:O() 
  15. *备注:无 
  16. *日期:2014/7/30 
  17. *算法描述: 
  18. */  
  19. #include "stdafx.h"  
  20. #include <iostream>  
  21. #include <stdlib.h>  
  22. #include <time.h>  
  23.   
  24. using namespace std;  
  25.   
  26. #define MAX 101  
  27. /* 
  28. *函数功能:产生指定的随机数 
  29. *函数原形:void RandNumIn(int num[]) 
  30. *参数:int num[],产生的随机数保存到数组num中 
  31. *返回值:无 
  32. */  
  33. void RandNumIn(int num[])  
  34. {  
  35.     int i;  
  36.   
  37.     srand((unsigned)time(NULL));       //得到随机种子  
  38.     for(i=1; i<MAX; i++)  
  39.         num[i]=100+rand()%900;             //生成100--999以内的随机三位整数  
  40. }  
  41. /* 
  42. *函数功能:输出产生的随机数 
  43. *函数原形:void RandNumOut(int num[]) 
  44. *参数:int num[],将要输出的数组 
  45. *返回值:无 
  46. */  
  47. void RandNumOut(int num[])  
  48. {  
  49.     int count=0;  
  50.     for(int i=1; i<MAX; i++)  
  51.     {  
  52.         cout<<num[i]<<"  ";  
  53.         count++;  
  54.         if(0==count%10)  
  55.             cout<<endl;  
  56.     }  
  57. }  
  58. /* 
  59. *函数功能:快速排序法 
  60. *函数原形:void QuickSort(int num[], int low, int high) 
  61. *参数: 
  62. int num[],要排序的数组,  
  63. int low, 查找的起始位置 
  64. int high,查找的末端位置 
  65. *返回值:无 
  66. */  
  67. void QuickSort(int num[], int low, int high)  
  68. {  
  69.     int l, h;  
  70.   
  71.     if(low<high)  
  72.     {  
  73.         l=low;  
  74.         h=high;  
  75.         num[0]=num[l];   
  76.   
  77.         while(l<h)  
  78.         {  
  79.             while(l<h && num[h]>=num[0])   
  80.                 h--;     //利用快速排序是数据有序  
  81.                 num[l]=num[h];  
  82.             while(l<h && num[l]<=num[0])   
  83.                 l++;  
  84.             num[h]=num[l];  
  85.         }  
  86.         num[l]=num[0];   
  87.   
  88.         QuickSort(num, low, l-1);  
  89.         QuickSort(num, l+1, high);  
  90.     }  
  91. }  
  92. /* 
  93. *函数功能:二分查找法查找指定的数 
  94. *函数原形:int SpecialFindNum(int num[], int x, int low, int high) 
  95. *参数: 
  96. int num[],要查找的数组,  
  97. int x,要查找的数 
  98. int low, 查找的起始位置 
  99. int high,查找的末端位置 
  100. *返回值:数字的位置 
  101. */  
  102. int SpecialFindNum(int num[], int x, int low, int high)  
  103. {  
  104.     int mid;                 //中间位置  
  105.     while(low<=high)  
  106.     {  
  107.         mid=(low+high)/2; /* 找到 */  
  108.   
  109.         if(x==num[mid])  
  110.             return mid;  
  111.         else if(x<num[mid])      //两边的游标不停往中间移动比较  
  112.             high=mid-1;  
  113.         else  
  114.             low=mid+1;  
  115.     }  
  116.     return 0;  
  117. }  
  118.   
  119. int _tmain(int argc, _TCHAR* argv[])  
  120. {  
  121.     int x, pos, num[MAX];  
  122.     RandNumIn(num);  
  123.     cout<<"排序前:"<<endl;  
  124.     RandNumOut(num);  
  125.     QuickSort(num, 1, MAX-1);  
  126.     cout<<"排序后:"<<endl;  
  127.     RandNumOut(num);  
  128.   
  129.     cout<<"请输入要查找的数:"<<endl;  
  130.     cin>>x;  
  131.     pos=SpecialFindNum(num, x, 1, MAX-1);            //调用查找函数  
  132.     if(pos)  
  133.         cout<<"太好了!"<<x<< "的位置在: "<< pos<<endl;  
  134.     else  
  135.         cout<<"抱歉"<<x<< "没有找到 "<<endl;  
  136.     system("pause");  
  137.     return 0;  
  138. }  


练习9,字符串中指定数据出现次数

  1. // ConsoleAppCharCount.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *问题描述:设计一个程序,统计随机给出的字符串的数字的个数,字母的个数,特殊字符的个数 
  5. *问题示例:123asd,数字3,字母3,特殊字符0 
  6. *函数功能:统计字符串中的数据 
  7. *函数原形:void CharCal(char *str, int count[]) 
  8. *参数:char *str,欲统计的字符串, int count[],用于存储统计结果 
  9. *返回值:无 
  10. *时间复杂度:O() 
  11. *备注:无 
  12. *日期:2014/7/30 
  13. *算法描述: 
  14. */  
  15. #include "stdafx.h"  
  16. #include <iostream>  
  17. #include <string.h>  
  18. #define MAX 1024  
  19. using namespace std;  
  20. /* 
  21. *函数功能:统计字符串中的数据 
  22. *函数原形:void CharCal(char *str, int count[]) 
  23. *参数:char *str,欲统计的字符串, int count[],用于存储统计结果 
  24. *返回值:无 
  25. */  
  26. void CharCal(char *str, int count[])  
  27. {  
  28.     while(*str)   
  29.     {  
  30.         if((*str>='0')&&(*str<='9'))      //统计数字型字符  
  31.             count[0]++;  
  32.         else if(((*str>='a')&&(*str<='z')) || ((*str>='A')&&(*str<='Z'))) //统计字符型字符  
  33.             count[1]++;                     
  34.         else                      //其他特殊字符  
  35.             count[2]++;  
  36.         str++;//指针移动  
  37.     }  
  38. }  
  39.   
  40. /* 
  41. *函数功能:输出统计结果 
  42. *函数原形:void CharCount( int count[]) 
  43. *参数: int count[],存储统计结果的数组 
  44. *返回值:无 
  45. */  
  46. void CharCount( int count[])  
  47. {  
  48.     for(int i=0; i<3; i++)  
  49.     {  
  50.         switch(i)  
  51.         {  
  52.         case 0:  
  53.             cout<<"数字:"<<count[i]<<endl;  
  54.             break;  
  55.         case 1:  
  56.             cout<<"字符:"<< count[i]<<endl;  
  57.             break;  
  58.         case 2:  
  59.             cout<<"特殊字符:"<<count[i]<<endl;  
  60.             break;  
  61.         }  
  62.     }   
  63. }  
  64.   
  65. int _tmain(int argc, _TCHAR* argv[])  
  66. {  
  67.     char str[MAX];                  //定义存储输入字符串的数组  
  68.     int  count[3];  //用于存储统计结果0->数字; 1->字符; 2->其他  
  69.     memset(count, 0, 3*sizeof(int));      //初始化统计数组  
  70.     cout<<"输入字符串: "<<endl;  
  71.     cin>>str;  
  72.     CharCal(str, count);//统计  
  73.     CharCount(count);//输出显示  
  74.     system("pause");  
  75.     return 0;  
  76. }  

练习10,逆序输出字符串

  1. // ConsoleAppCharTest.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /*  
  4. *问题描述:输入字符串,将其逆序输出 
  5. *问题示例:输入,asdfgh,输出hgfdsa 
  6. *函数功能:逆序输出字符串的内容 
  7. *函数原形:void Reverse( char* s, int left, int right ); 
  8. *参数: 
  9. char *,欲逆序的字符串, 
  10. int left, 逆序的左起点 
  11. int right,逆序的右尾点 
  12. *返回值:无  
  13. *时间复杂度:O(n)  
  14. *备注:无  
  15. *日期:2014/7/30  
  16. *算法描述:  
  17. */   
  18. #include "stdafx.h"  
  19. #include<iostream>  
  20.   
  21. using namespace std;  
  22.   
  23. void Reverse( char* s, int left, int right );  
  24. int _tmain(int argc, _TCHAR* argv[])  
  25. {  
  26.   
  27.     int len;  
  28.     char a[100];  
  29.   
  30.     while(1)  
  31.     {  
  32.         cout<<"请输入字符串a:"<<endl;  
  33.         cin>>a;  
  34.         len=strlen(a);  
  35.         Reverse(a,0,len-1);  
  36.         for(int i=0;i<len;i++)  
  37.             cout<<a[i];  
  38.         cout<<endl;  
  39.     }  
  40.   
  41.     return 0;  
  42. }  
  43.   
  44. //算法一: 对字符串s在指定区间left和right之间进行逆序,递归法  
  45. void Reverse( char* s, int left, int right )  
  46. {  
  47.     if(left >= right)  
  48.         return;  
  49.   
  50.     char t = s[left] ;  
  51.     s[left] = s[right] ;  
  52.     s[right] = t ;  
  53.     Reverse(s, left + 1, right - 1) ;  
  54. }  
  55. /* 
  56. //算法二:与上面的方法没有太大区别 
  57. void Reverse( char* s, int left, int right ) 
  58. { 
  59.     while( left < right ) 
  60.     { 
  61.         char t = s[left] ; 
  62.         s[left++] = s[right] ; 
  63.         s[right--] = t ; 
  64.     } 
  65. }*/  


练习11,字符串包含判断

  1. // ConsoleAppCharTest.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /*  
  4. *问题描述:输入两个字符串,判断相互之间字符串是否包含 
  5. *问题示例:输入,asdfgh,输出asd,结果,包含! 
  6. *函数功能:判断两个字符串是否包含 
  7. *函数原形:bool IsContain(char *pStrA, char *pStrB); 
  8. *参数: 
  9. char *pStrA, 第一个字符串 
  10. char *pStrB,第二个字符串 
  11. *返回值:布尔变量  
  12. *时间复杂度:O(n)  
  13. *备注:无  
  14. *日期:2014/7/30  
  15. *算法描述:  
  16. */   
  17. #include "stdafx.h"  
  18. #include "iostream"  
  19.   
  20.   
  21. using namespace std;  
  22.   
  23.   
  24. bool IsContain(char *pStrA, char *pStrB);  
  25.   
  26.   
  27. int _tmain(int argc, _TCHAR* argv[])  
  28. {  
  29.     char a[10],b[10];  
  30.     bool flag;  
  31.     while(true)  
  32.     {  
  33.         cout<<"Please Enter characters A:"<<endl;  
  34.         cin>>a;  
  35.         cout<<"Please Enter characters B:"<<endl;  
  36.         cin>>b;  
  37.   
  38.   
  39.         flag=IsContain(a, b);  
  40.   
  41.   
  42.         if (flag==false)  
  43.             cout<<"Not Contain!"<<endl;  
  44.         else  
  45.             cout<<"Contain!"<<endl;  
  46.     }  
  47.     return 0;  
  48.   
  49.   
  50. }  
  51. //算法1  
  52. bool IsContain(char *pStrA, char *pStrB)  
  53. {  
  54.     int lenA = strlen(pStrA);  
  55.     int lenB = strlen(pStrB);  
  56.     int i,j;  
  57.     char temp;  
  58.     for( i = 0; i < lenA; i++)   
  59.     {//直接对字符数组A进行循环移位再立马进行字符包含判断  
  60.         temp = pStrA[0];  
  61.         for( j = 0; j < lenA - 1; j++)  
  62.             pStrA[ lenA - 1] = pStrA[j + 1];  
  63.         pStrA[j] = temp;  
  64.         if(strncmp(pStrA, pStrB, lenB) == 0)  
  65.             return true;  
  66.     }  
  67.     //若果执行到最后都还没有匹配成功,则返回false  
  68.     if(i == lenA)     
  69.         return false;  
  70. }/* 
  71. //算法2 
  72. bool IsContain(char *pStrA, char *pStrB) 
  73. { 
  74. int lenp = strlen(pStrA); 
  75. char *temp = (char*)malloc(2 * lenp + 1);//动态分配内存 
  76. strcpy_s(temp,2 * lenp + 1,pStrA); 
  77. strcpy_s(temp + lenp, 2 * lenp + 1,pStrA); 
  78.  
  79.  
  80. if(strstr(temp, pStrB))  
  81. return TRUE; 
  82. else  
  83. return FALSE; 
  84. }*/  


练习12,打印任意位元的格雷码序列:

比如3位的所有格雷码:

000
001
011
010
110
111
101
100


代码如下:

  1. // ConsoleAppGrayCode.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6.   
  7. using namespace std;  
  8.   
  9. bool GrayCode(int nBits);  
  10. int changeBit(int a);  
  11. int _tmain(int argc, _TCHAR* argv[])  
  12. {  
  13.     int nBits=0;  
  14.     cout<<"请输入位元长度:"<<endl;  
  15.     cin>>nBits;  
  16.     GrayCode(nBits);  
  17.     system("pause");  
  18.     return 0;  
  19. }  
  20.   
  21. bool GrayCode(int nBits)  
  22. {  
  23.     bool flag=true;  
  24.     do   
  25.     {  
  26.         if (nBits<0)  
  27.         {  
  28.             cout<<"你的输入有误,请重新输入:"<<endl;  
  29.             cin>>nBits;  
  30.         }else  
  31.         {  
  32.             flag=false;  
  33.         }  
  34.     } while (flag);  
  35.     int *pGray=new int[nBits];  
  36.     for (int i=0;i<nBits;i++)  
  37.     {  
  38.         pGray[i]=0;  
  39.         cout<<0;  
  40.     }  
  41.     cout<<endl;  
  42.   
  43.     for (int j=1;j<pow(2,nBits);j++)  
  44.     {  
  45.         if (j%2==1)  
  46.         {  
  47.             pGray[nBits-1]=changeBit(pGray[nBits-1]);  
  48.             for (int i=0;i<nBits;i++)  
  49.             {  
  50.                 cout<<pGray[i];  
  51.             }  
  52.             cout<<endl;  
  53.         }else  
  54.         {  
  55.             int j=0;  
  56.             for ( j=nBits-1;j>=0;j--)  
  57.             {  
  58.                 if (pGray[j]==1)  
  59.                 {  
  60.                     pGray[j-1]=changeBit(pGray[j-1]);  
  61.                     break;  
  62.                 }  
  63.             }  
  64.             for (int i=0;i<nBits;i++)  
  65.             {  
  66.                 cout<<pGray[i];  
  67.             }  
  68.             cout<<endl;  
  69.         }  
  70.     }  
  71.   
  72.     return true;  
  73. }  
  74. int changeBit(int a)  
  75. {  
  76.     if (a==0)  
  77.     {  
  78.         return 1;  
  79.     }else  
  80.     {  
  81.         return 0;  
  82.     }  
  83. }  


另一份可参考代码:
  1. #include <iostream>  
  2. using namespace std;  
  3. #define CHANGE_BIT(a) a=((a=='0')? '1':'0')             //定义宏实现改变位元值  
  4. #define NEXT_BIT(x) x=(1-(x))                         //设定奇数项或偶数项  
  5. /***************构建n位元的格雷码***************/  
  6. void findGrayCode(int n){  
  7.     if (n <=0)  
  8.     {  
  9.         cout<<"输入超出有效范围"<<endl;             //验证输入值是否合法  
  10.         return;  
  11.     }  
  12.     char* gray=new char[n];                          //声明存储每个格雷码的数组  
  13.     for (int i=0;i<n;i++)                               //初始化数组为0  
  14.     {  
  15.         gray[i] = '0';  
  16.         cout<<'0';                                  //打印其实格雷码0000...  
  17.     }  
  18.     cout<<endl;  
  19.     int odd = 1;                                     //定义奇数标志,1为奇数项,0为偶数项  
  20.     int i=0;      
  21.     /**********************循环构造并输出格雷码*************************/  
  22.     while(1){  
  23.         if (odd)                                 //如果为奇数项,更改最右边位元值为相反值  
  24.         {  
  25.             CHANGE_BIT(gray[0]);             //本题为反向存储  
  26.         }else{  
  27.             /***********************如果为偶数项则查找从数的右边起第一个1的位置*************/  
  28.             for (i=0;i<n && gray[i]=='0';i++);  
  29.             if (i==n-1)                     //如果i为数的最左边位,则退出循环,所有格雷码查找完成  
  30.                 break;                           
  31.             CHANGE_BIT(gray[i+1]);          //更改第一个1左边的以为的值  
  32.         }  
  33.         for (i=n-1;i>=0;i--)                      //输出改格雷码  
  34.         {  
  35.             cout<<gray[i];  
  36.         }  
  37.         cout<<endl;  
  38.         NEXT_BIT(odd);                       //更改奇偶属性  
  39.     }  
  40. }  
  41. /**************************测试主函数*************************/  
  42. int main(){  
  43.     int n;  
  44.     cout<<"输入位元数:"<<endl;  
  45.     cin>>n;  
  46.     cout<<n<<"位元的格雷码为:"<<endl;  
  47.     findGrayCode(n);  
  48.     return 0;  
  49. }  


练习14,约舍夫出局

N个人围成一圈,从第一个开始报数,第M个将出局,最后剩下一个,其余人都将出局。

例如N=6,M=5,被出局的顺序是:5,4,6,2,3,1。

(1)CircleList.h的代码如下:

  1. #include "stdafx.h"  
  2. #include "iostream"  
  3.   
  4. using namespace std;  
  5. template<class DataType>class LinkList;  
  6. template<class DataType>  
  7. class LinkNode  
  8. {  
  9. public:  
  10.     LinkNode()  
  11.     {  
  12.         next = NULL;  
  13.         data = 0;  
  14.     }  
  15.     //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面  
  16.     LinkNode(DataType item)      
  17.     {  
  18.         next = NULL;  
  19.         data = item;  
  20.     }  
  21.     friend class LinkList<DataType>;  
  22.   
  23. private:  
  24.     DataType data;  
  25.     LinkNode<DataType> *next;  
  26. };  
  27.   
  28. /* 带头结点的单链表定义 */  
  29. template<class DataType>  
  30. class LinkList  
  31. {  
  32. public:  
  33.     //无参数的构造函数  
  34.     LinkList(int size)  
  35.     {  
  36.         head = new LinkNode<DataType>;//头结点  
  37.         maxSize=size;  
  38.         nLength=0;  
  39.     }  
  40.     //析构函数  
  41.     ~LinkList()  
  42.     {  
  43.     }  
  44.     //获取链表长度  
  45.     int Length() const  
  46.     {  
  47.         return nLength;  
  48.     }  
  49.     //定位指定的位置,返回该位置上的结点指针  
  50.     LinkNode<DataType>* Locate(int pos);  
  51.     //在指定位置pos插入值为item的结点,失败返回false  
  52.     bool Insert(DataType item, int pos);  
  53.     //打印链表  
  54.     void Print() const;  
  55.     //创建一个链表环  
  56.     void CreatCircle();  
  57.       
  58.     //判断是否纯在单链表环  
  59.     bool IsCircle();  
  60.     //数数移动  
  61.     bool CountMove( int nStep=0 ,int i=0 );  
  62.       
  63. private:  
  64.     LinkNode<DataType> *head;  
  65.     int maxSize;  
  66.     int nLength;  
  67. };  
  68.   
  69. /* 返回链表中第pos个元素的地址,如果pos<0或pos超出链表最大个数返回NULL */  
  70. template<class DataType>  
  71. LinkNode<DataType>* LinkList<DataType>::Locate(int pos)  
  72. {  
  73.     LinkNode<DataType> *p = head;//head和p指向共同的内容,头结点无数据,只是个指针  
  74.   
  75.     if (pos < 0)  
  76.     {  
  77.         cerr<<"位置参数有错误"<<endl;  
  78.         return NULL;  
  79.     }  
  80.   
  81.     int i = 0;  
  82.     while (p != NULL && i < pos)  
  83.     {  
  84.         p = p->next;  
  85.         i++;  
  86.     }  
  87.   
  88.     return p;  
  89. }  
  90.   
  91. template<class DataType>  
  92. bool LinkList<DataType>::Insert(DataType item, int pos)  
  93. {  
  94.     if (Length() >= maxSize)  
  95.     {  
  96.         cout<<"错误:链表已满"<<endl;  
  97.         exit(1);  
  98.     }  
  99.     LinkNode<DataType> *p = Locate(pos);  
  100.   
  101.     LinkNode<DataType> *newNode = new LinkNode<DataType>(item);//创建新节点  
  102.     if (NULL == newNode)  
  103.     {  
  104.         cerr << "分配内存失败!" << endl;  
  105.         exit(1);  
  106.     }  
  107.     newNode->next = p->next;  
  108.     p->next = newNode;  
  109.     nLength++;  
  110.     return true;  
  111. }  
  112.   
  113.   
  114. template<class DataType>  
  115. void LinkList<DataType>::Print() const  
  116. {  
  117.     int count = 0;  
  118.     LinkNode<DataType> *p = head;  
  119.     while (NULL != p->next)  
  120.     {  
  121.         p = p->next;  
  122.         std::cout << p->data << " ";  
  123.         if (++count % 15 == 0)  //每隔十个元素,换行打印  
  124.             cout << std::endl;  
  125.     }  
  126. }  
  127.   
  128. //创建一个链表环  
  129. template<class DataType>  
  130. void LinkList<DataType>:: CreatCircle()  
  131. {  
  132.     int nLen=Length();  
  133.     int nLen1=1;  
  134.     LinkNode<DataType> *ptail=Locate(nLen);  
  135.     LinkNode<DataType> *pcirStart=Locate(nLen1);  
  136.     ptail->next=pcirStart;  
  137. }  
  138.   
  139.   
  140. //是否纯在链表环?  
  141. template<class DataType>  
  142. bool LinkList<DataType>::IsCircle()  
  143. {  
  144.     if ( head ==NULL)  
  145.     {  
  146.         cerr<<"空链表"<<endl;  
  147.         exit(1);  
  148.     }  
  149.     LinkNode<DataType> *pFast,*pSlow;  
  150.     pSlow=head;  
  151.     pFast=head;  
  152.     while(pFast!=NULL&&pFast->next!=NULL)  
  153.     {  
  154.         pFast=pFast->next->next;  
  155.         pSlow=pSlow->next;  
  156.         if (pSlow==pFast)  
  157.         {  
  158.             return true;  
  159.             break;  
  160.         }  
  161.     }  
  162.     return false;  
  163. }  
  164.   
  165. <pre name="code" class="html">template<class DataType>  
  166. bool LinkList<DataType>::CountMove( int nStep,int k)//指定出局人数  
  167. {  
  168.   
  169.     if (  k > Length() )  
  170.     {  
  171.         cerr<<"写你麻痹,滚回去检查!"<<endl;  
  172.         return false;  
  173.     }  
  174.       
  175.     LinkNode<DataType> *pCurr=NULL,*pPrev=NULL;    
  176.     int i = 0;    // 计数    
  177.     int n=0;  
  178.     pCurr = pPrev = head;    
  179.     while( n < k )    
  180.     {    
  181.         if (i == nStep)    
  182.         {    
  183.             // 踢出环    
  184.             cout<<"第 "<<n+1<<" 次出局"<<":  ";  
  185.             cout<<"当前出局人编号"<<pCurr->data<<endl;    // 显示出圈循序    
  186.             pPrev->next = pCurr->next;    
  187.             delete pCurr;    
  188.             pCurr = pPrev->next;    
  189.             i = 1;    
  190.             n++;  
  191.         }    
  192.         pPrev = pCurr;    
  193.         pCurr = pCurr->next;    
  194.         if (pPrev == pCurr)    
  195.         {    
  196.             // 最后一个    
  197.             cout<<"第 "<<n+1<<" 次出局"<<":  ";  
  198.             cout<<"最后的出局人为:"<<pCurr->data<<" ";    // 显示出圈循序    
  199.             delete pCurr;    
  200.             //最后一个节点删除后的“擦屁股”处理  
  201.             pCurr=NULL;  
  202.             head->next=head;  
  203.             n++;  
  204.             break;    
  205.         }    
  206.         i++;    
  207.     }    
  208.     return true;  
  209. }  

(2)主测试代码:

  1. // Win32AppCircleOut.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "CircleList.h"  
  6.   
  7. using namespace std;  
  8.   
  9. int _tmain(int argc, _TCHAR* argv[])  
  10. {  
  11.     int nlen=10;  
  12.     LinkList<int> s(nlen);  
  13.     for (int i=0;i<nlen;i++)  
  14.     {  
  15.         s.Insert(i+1,i);  
  16.     }  
  17.     s.CreatCircle();  
  18.     if (s.IsCircle())  
  19.     {  
  20.         cout<<"环已经生成,可以开始了!"<<endl;  
  21.     }  
  22.     s.CountMove(3,10);//数到3出局,记录前30个人的出局情况  
  23.     system("pause");  
  24.     return 0;  
  25. }  


练习15,汉诺塔递归

汉诺塔递归问题:


  1. // ConsoleAppHanoi.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6.   
  7. using namespace std;  
  8. int Hanoicount=0;  
  9. bool HanoiMove(int n,char a,char b,char c);//将n个盘从a借助b移动到c  
  10.   
  11. int _tmain(int argc, _TCHAR* argv[])  
  12. {  
  13.     HanoiMove(5,'A','B','C');  
  14.     cout<<"共进行了:"<<Hanoicount<<"次"<<endl;  
  15.     system("pause");  
  16.     return 0;  
  17. }  
  18.   
  19.   
  20. bool HanoiMove(int n,char a,char b,char c)  
  21. {  
  22.       
  23.     if ( n == 1 )  
  24.     {  
  25.         cout<<a<<"-------->"<<c<<endl;  
  26.         Hanoicount++;  
  27.     }else  
  28.     {  
  29.         HanoiMove(n-1,a,c,b);  
  30.         cout<<a<<"-------->"<<c<<endl;  
  31.         HanoiMove(n-1,b,a,c);  
  32.         Hanoicount++;  
  33.     }  
  34.     return true;  
  35. }  



练习,16求某年某月某日是当年的第几天

  1. / ConsoleAppRunNian.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6. #include "windows.h"  
  7. using namespace std;  
  8.   
  9. int leap(int a)                                     /*自定义函数leap用来指定年份是否为闰年*/    
  10. {    
  11.     if (a % 4 == 0 && a % 100 != 0 || a % 400 == 0)             /*闰年判定条件*/    
  12.         return 1;                                   /*是闰年返回1*/    
  13.     else    
  14.         return 0;                                   /*不是闰年返回0*/    
  15. }    
  16.   
  17. int number(int year, int m, int d) /*自定义函数number计算输入日期为该年第几天*/    
  18. {    
  19.     if ( m>12 || d > 31 || d < 0 || m<0)  
  20.     {  
  21.         cerr<<"参数错误!"<<endl;  
  22.         return -1;  
  23.     }  
  24.     if (m ==2)  
  25.     {  
  26.         if (d > 29)  
  27.         {  
  28.             cerr<<"参数错误!"<<endl;  
  29.             return -1;  
  30.         }  
  31.     }  
  32.     int sum = 0, i;     
  33.     /*数组a存放平年每月的天数*/    
  34.     int a[12] ={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};                                                
  35.     int b[12] ={31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};      /*数组b存放闰年每月的天数*/    
  36.     if (leap(year) == 1)                                /*判断是否为闰年*/    
  37.         for (i = 0; i < m - 1; i++)    
  38.             sum += b[i];                                /*是闰年,累加数组b前m-1个月份天数*/    
  39.     else    
  40.         for (i = 0; i < m - 1; i++)    
  41.             sum += a[i];                                /*不是闰年,累加数组a钱m-1个月份天数*/    
  42.     sum += d;                                       /*将前面累加的结果加上日期,求出总天数*/    
  43.     return sum;                                     /*将计算的天数返回*/    
  44. }    
  45.   
  46. void main()    
  47. {    
  48.     int year, month, day, n;           /*定义变量为基本整型*/    
  49.     cout<<"请输入年月日"<<endl;    
  50.     cin>>year>>month>>day;             /*输入年月日*/    
  51.     n = number(year, month, day);                           /*调用函数number*/    
  52.       
  53.     while (n == -1)  
  54.     {  
  55.         cout<<"请重新输入年月日"<<endl;    
  56.         cin>>year>>month>>day;             /*输入年月日*/    
  57.         n = number(year, month, day);                           /*调用函数number*/   
  58.     }  
  59.       
  60.     cout<<"第"<<n<<"天"<<endl;   
  61.     Sleep(5000);    
  62. }  




练习17,逻辑推理题

婚礼上的谎言



  1. // ConsoleAppHunLi.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6. #include "windows.h"  
  7. using namespace std;  
  8.   
  9. int _tmain(int argc, _TCHAR* argv[])  
  10. {  
  11.     int a, b, c;  
  12.     for (a = 1; a <= 3; a++)                             /*穷举a的所有可能*/  
  13.         for (b = 1; b <= 3; b++)                         /*穷举b的所有可能*/  
  14.             for (c = 1; c <= 3; c++)                     /*穷举c的所有可能*/  
  15.                 if (a != 1 && c != 1 && c != 3 && a != b && a != c && b != c)  
  16.                     /*如果表达式为真,则输出结果,否则继续下次循环*/  
  17.                 {  
  18.                     cout<<char('X' + a - 1)/*转换数据类型*/<<" 将嫁给 A"<<endl;  
  19.                     cout<<char('X' + b - 1)<<" 将嫁给 B"<<endl;  
  20.                     cout<<char('X' + c - 1)<<" 将嫁给 C"<<endl;  
  21.                 }  
  22.                 Sleep(5000);  
  23.     return 0;  
  24. }  

练习18,二维数组转换为一维数组:

  1. // ConsoleAppMatTrans.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6. using namespace std;  
  7.   
  8. /******************  
  9. 定义二维数组char array[x][y];   
  10. 1.只定义个一维的就可以了   
  11. char *array;   
  12. array = new char[x*y]; 这种方式等价于char *array = new char[x*y];  
  13. 访问的时候*(array+i*y+j)表示array[i][j]   
  14. 2.定义一个二维数组   
  15. char **array1   
  16. array1 = new char *[x];   
  17. for(i=0;i<x;++i)   
  18. array1[i] = new char[y];   
  19. ...用的时候可以直接array1[i][j]   
  20. 注意delete  
  21. *************/  
  22. int Trans2DArray(int **src2dArr,int nrow,int ncol,int *dst1dArr);  
  23. int _tmain(int argc, _TCHAR* argv[])  
  24. {  
  25.     int** mat;  
  26.     int row=3,col=3;//row为行数  
  27.     cout<<"请输入二维数组的行数和列数(空格隔开,比如“3 3”)"<<endl;  
  28.     cin>>row>>col;  
  29.     mat =new int*[row];//二维数组的每行的指针  
  30.     cout<<"请输入二维数组:"<<endl;  
  31.     for (int i=0;i<row;i++)  
  32.     {  
  33.         mat[i] = new int[col];  
  34.         for (int j=0;j<col;j++)  
  35.         {  
  36.             cin>>mat[i][j];  
  37.         }  
  38.     }  
  39.       
  40.     cout<<"二维数组为:"<<endl;  
  41.     int count=0;  
  42.     for (int i=0;i<row;i++)  
  43.     {  
  44.         for (int j=0;j<col;j++)  
  45.         {  
  46.             cout<<mat[i][j]<<" ";  
  47.             count++;  
  48.         }  
  49.         if ( count%col == 0 )  
  50.         {  
  51.             cout<<endl;  
  52.         }  
  53.     }  
  54.     int *arr =new int[row*col];  
  55.     for (int n=0;n<row*col;n++)  
  56.     {  
  57.         arr[n]=0;  
  58.     }  
  59.     Trans2DArray(mat,row,col,arr);  
  60.     cout<<"转换后的一维数组为:"<<endl;  
  61.     for (int k=0;k < row*col;k++)  
  62.     {  
  63.         cout<<arr[k]<<" ";  
  64.     }  
  65.     delete[] arr;  
  66.     system("pause");  
  67.     return 0;  
  68. }  
  69.   
  70. int Trans2DArray(int **src2dArr,int nRow,int nCol,int *dst1dArr)  
  71. {  
  72.     if (src2dArr == NULL || nRow < 0 || nCol <0)  
  73.     {  
  74.         cerr<<"参数错误"<<endl;  
  75.         return 0;  
  76.     }  
  77.     for (int i=0;i<nRow;i++)  
  78.     {  
  79.         for (int j=0;j<nCol;j++)  
  80.         {  
  81.             dst1dArr[j+i*nCol]=src2dArr[i][j];//j+i*nCol表示第i行j列的数据  
  82.         }  
  83.     }  
  84.     return 1;  
  85. }  






练习19,求取一个二进制数的长度


定义:二进制长度就是最高位1的下标值+1(下标从0开始),比如16 = 10000,则长度是5, 2= 0010,长度为2

  1. #include "stdafx.h"  
  2. #include "iostream"  
  3. using namespace std;  
  4.   
  5. int BitLength(unsigned int n);  
  6.   
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     int count=0,a;  
  10.     do   
  11.     {  
  12.     cout<<"请输入一个整数"<<endl;  
  13.     cin>>a;  
  14.     count=BitLength(a);  
  15.     cout<<"该整数对应二进制数的长度为:"<<count<<endl;  
  16.     } while (a>0);  
  17.     return 0;  
  18. }  
  19. //算法一:易阅读  
  20. int BitLength(unsigned int n)  
  21. {  
  22.     int c = 0 ;  //计数  
  23.     while (n)  
  24.     {  
  25.         ++c ;  
  26.         n >>= 1 ;  
  27.     }  
  28.     return c ;  
  29. }  
  30. //算法二:与上面的解法本质一样  
  31. int BitLength(unsigned int n)   
  32. {   
  33.     return n ? BitLength1(n >>=1) + 1 : 0 ;   
  34. }  
  35. //算法三:以空间换时间(参考网络)  
  36. int BitLength(unsigned int n)   
  37. {   
  38.     // pow of 2, 2^0 - 2 ^31   
  39.     int powof2[32] =   
  40.     {   
  41.                  1,           2,           4,           8,         16,          32,   
  42.                 64,         128,         256,         512,       1024,        2048,   
  43.               4096,        8192,       16384,       32768,      65536,      131072,   
  44.             262144,      524288,     1048576,     2097152,    4194304,     8388608,   
  45.           16777216,    33554432,    67108864,   134217728,  268435456,   536870912,   
  46.         1073741824,  2147483648   
  47.     } ;   
  48.   
  49.     int left = 0 ;   
  50.     int right = 31 ;   
  51.   
  52.     while (left <= right)   
  53.     {   
  54.         int mid = (left + right) / 2 ;   
  55.   
  56.         if (powof2[mid] <= n)   
  57.         {   
  58.             if (powof2[mid + 1] > n)   
  59.                 return mid + 1; // got it!   
  60.             else // powof2[mid] < n, search right part  
  61.                 left = mid + 1 ;   
  62.         }   
  63.   
  64.         else // powof2[mid] > n, search left part   
  65.             right = mid - 1 ;   
  66.     }   
  67.    
  68.     return -1 ;   
  69. }  


练习20,求两个正整数的最大公约数

碾转相除法:假设f(a,b)是a,b的最大公约数,则f(b,a%b)=f(a,b),即f(b,a%b)同样也是其最大公约数


  1. #include "stdafx.h"  
  2. #include<iostream>  
  3. using namespace std;  
  4.   
  5. int GyueNum(int x,int y);  
  6.   
  7. int main()  
  8. {  
  9.     int a,b,result;  
  10.     cout<<"请输入两个任意的整数"<<endl;  
  11.     cin>>a>>b;  
  12.     result=GyueNum(a,b);  
  13.     cout<<result<<endl;  
  14.     system("pause");  
  15.     return 0;  
  16. }  
  17. //算法实现1:  
  18. int GyueNum(int x,int y)  
  19. {  
  20.     return (!y)?x:GyueNum(y,x%y);//碾转相除法  
  21. }  


练习21,栈的顺序输出(STL库实现)


  1. // ConsoleAppStackTest1.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. /* 
  4. *函数功能:以 23 56 11 4 87 98入栈,以11 4 56 98 87 23出栈 
  5. *函数原形:无 
  6. *参数:无 
  7. *返回值:无 
  8. *时间复杂度:无 
  9. *备注:无 
  10. *日期:2014/12/13 
  11. *原创:是 
  12. *作者:EbowTang 
  13. *Email:tangyibiao520@163.com 
  14. */  
  15. #include "stdafx.h"  
  16. #include <iostream>  
  17. #include <stack>  
  18.   
  19. using namespace std;  
  20.   
  21. int _tmain(int argc, _TCHAR* argv[])  
  22. {  
  23.     //顺序入栈,三个参数  
  24.     stack<int> sta;  
  25.       
  26.     sta.push( 23 );  
  27.     sta.push( 56 );  
  28.     sta.push( 11 );  
  29.   
  30.     cout << sta.top( )<< " ";//输出顶值11  
  31.     sta.pop( );//删除元素11  
  32.       
  33.     sta.push( 4 );  
  34.   
  35.     cout << sta.top( )<< " ";//输出顶值4  
  36.     sta.pop( );//删除元素4  
  37.     cout << sta.top( ) << " ";//输出顶值56  
  38.     sta.pop( );//删除元素56  
  39.     sta.push( 87 );  
  40.     sta.push( 98 );  
  41.     cout << sta.top( ) << " ";//输出顶值98  
  42.     sta.pop( );//删除元素98  
  43.     cout << sta.top( ) << " ";//输出顶值87  
  44.     sta.pop( );//删除元素87  
  45.     cout << sta.top( ) << " ";//输出顶值23  
  46.   
  47.     system( "PAUSE" );  
  48.     return EXIT_SUCCESS;  
  49. }  


练习22,括号配对问题

描述
现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0<N<=100),表示有N组测试数据。后面的N行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[","]","(",")"四种字符
输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No
样例输入
3
[(])
(])
([[]()])
样例输出
No
No
Yes


难度3,第2题

方法:(栈的基本运用)
解题思路依次扫描整个字符串,并使用栈进行模拟。对于输入括号(如果不特殊指出,这里的
括号均指的是含圆括号和中括号)
1,如果为左型的括号(比如 “[”   “(”)则入栈
2,如果为右型括号且栈为空或栈顶元素与之不配对则输出No,反之弹出栈顶元素
3,重复1和2步骤直到扫描结束,最后检查栈是否为空,若为空输出Yes反之输出No。

“括号配对”代码实现如下:

  1. <span style="font-size:12px;">#include "iostream"    
  2. #include "string"    
  3. #include "stack"    
  4.   
  5. using namespace std;  
  6.   
  7. bool BracketMatch(const string srcStr);  
  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     system("color 0A");  
  11.     int N = 0;  
  12.     //申请内存    
  13.     string src;  
  14.     while (cin>>N)  
  15.     {  
  16.         for (size_t i = 0; i < N; i++)  
  17.         {  
  18.             cin >> src;  
  19.             if (BracketMatch(src))  
  20.                 cout << "YES" << endl;  
  21.             else  
  22.                 cout << "NO" << endl;  
  23.         }  
  24.     }  
  25.     return 0;  
  26. }  
  27.   
  28. bool BracketMatch(const string srcStr)  
  29. {  
  30.     stack<char> s;  
  31.     //例子[]()[];    
  32.     if (srcStr[0] == ')' || srcStr[0] == ']')//如果第一个字符就是右括号,则直接pass掉    
  33.         return false;  
  34.           
  35.     for (unsigned int i = 0; i < srcStr.length(); i++)//从左往右开始遍历    
  36.     {  
  37.         switch (srcStr[i])  
  38.         {  
  39.             //对左括号仅作压栈处理,同时值得注意的是栈中只有左括号  
  40.             case '[':  
  41.                     s.push(srcStr[i]);  
  42.                     break;  
  43.             case '(':  
  44.                     s.push(srcStr[i]);  
  45.                     break;  
  46.   
  47.             //对于右括号总是判断他是否与栈顶元素配对,否则即可判断不配对    
  48.             case ']':  
  49.                     if (s.top() == '[')  
  50.                         s.pop();  
  51.                     break;  
  52.             case ')':  
  53.                     if (s.top() == '(')  
  54.                         s.pop();  
  55.                     break;  
  56.   
  57.             default:  
  58.                     cerr << "错误的括号" << endl;  
  59.                     exit(1);  
  60.         }  
  61.           
  62.     }  
  63.     //判断栈中的情况  
  64.     if (s.empty())  
  65.         return true;  
  66.     else//如果栈中有数据则说明存在不匹配  
  67.         return false;  
  68. }</span>  


练习23,奇偶数分离

描述
有一个整型偶数n(2<= n <=10000),你要做的是:先把1到n中的所有奇数从小到大输出,再把所有的偶数从小到大输出。
输入
第一行有一个整数i(2<=i<30)表示有 i 组测试数据;
每组有一个整型偶数n。
输出
第一行输出所有的奇数
第二行输出所有的偶数
样例输入
2
10
14
样例输出
1 3 5 7 9 
2 4 6 8 10 

1 3 5 7 9 11 13 
2 4 6 8 10 12 14 


难度1,第11题
方法:
直接破题,即直接根据题意输出指定内容

“奇偶数分离”代码实现如下:
  1. // ConsoleAppAcmTest11.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6.   
  7. using namespace std;  
  8.   
  9. void OddEvenSepar(int *num, int N)  
  10. {  
  11.     for (int i = 0; i < N;i++)  
  12.     {  
  13.           
  14.         int k = 1;  
  15.         while (k < num[i])  
  16.         {  
  17.             if (k % 2 == 1)  
  18.             {  
  19.                 cout << k << "  ";  
  20.             }  
  21.             k++;  
  22.         }  
  23.         cout << endl;  
  24.   
  25.         int kk = 1;  
  26.         while (kk < num[i])  
  27.         {  
  28.             if (kk % 2 == 0)  
  29.             {  
  30.                 cout << kk << "  ";  
  31.             }  
  32.             kk++;  
  33.         }  
  34.         cout << endl;  
  35.      }  
  36. }  
  37. int _tmain(int argc, _TCHAR* argv[])  
  38. {  
  39.     system("color 0A");  
  40.     int N = 0;  
  41.     cout << "请输入测试组数:" << endl;  
  42.     cin >> N;  
  43.     int *num = new int[N];  
  44.     cout << "请输入对应个数的偶数" << endl;  
  45.     for (int i = 0; i < N;i++)  
  46.     {  
  47.         cin>>num[i];  
  48.     }  
  49.     cout << endl;  
  50.     OddEvenSepar(num, N);  
  51.   
  52.     delete[] num;  
  53.     num = NULL;  
  54.     system("pause");  
  55.     return 0;  
  56. }  



练习24,五个数求最值

描述
设计一个从5个整数中取最小数和最大数的程序
输入
输入只有一组测试数据,为五个不大于1万的正整数
输出
输出两个数,第一个为这五个数中的最小值,第二个为这五个数中的最大值,两个数字以空格格开。
样例输入
1 2 3 4 5
样例输出
1 5



难度:1,第31题

方法:

排序法,或者直接求取

“五个数求最值”代码实现如下:

  1. // ConsoleAppAcmTest31.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6.   
  7. using namespace std;  
  8.   
  9. void getMinMax(int *num,int n)  
  10. {  
  11.     int min = num[0], max = num[0];  
  12.     for (int j = 0; j < n;j++)  
  13.     {  
  14.         if (min>num[j])  
  15.         {  
  16.             min = num[j];  
  17.         }  
  18.         if (max < num[j])  
  19.         {  
  20.             max = num[j];  
  21.         }  
  22.     }  
  23.     cout << "最小值为:" << min << endl;  
  24.     cout << "最大值为:" << max << endl;  
  25. }  
  26. int _tmain(int argc, _TCHAR* argv[])  
  27. {  
  28.     system("color 0A");  
  29.     int num[5] = {0};  
  30.     for (int i = 0; i < 5;i++)  
  31.     {  
  32.         cin >> num[i];  
  33.     }  
  34.       
  35.     getMinMax(num,5);  
  36.     system("pause");  
  37.     return 0;  
  38. }  



练习25,韩信点兵

描述
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100 。
输入
输入3个非负整数a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7)。例如,输入:2 4 5
输出
输出总人数的最小值(或报告无解,即输出No answer)。实例,输出:89
样例输入
2 1 6
样例输出
41

难度1,第34题

方法:

暴力破解,遍历出答案

  1. // ConsoleAppAcmTest34.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "iostream"  
  6.   
  7. using namespace std;  
  8.   
  9. int HanXinCount(int *num);  
  10. int _tmain(int argc, _TCHAR* argv[])  
  11. {  
  12.     system("color 0A");  
  13.     int *num = new int[3];  
  14.     cout << "请输入3种排列方式的队尾人数:"<<endl;  
  15.     for (int i = 0; i < 3;i++)  
  16.     {  
  17.         cin >> num[i];  
  18.     }  
  19.     int persons = HanXinCount(num);  
  20.     if (persons==-1)  
  21.     {  
  22.         cout << "No Answer" << endl;  
  23.     }  
  24.     else  
  25.     {  
  26.         cout << "人数共为:" << persons << endl;  
  27.     }  
  28.       
  29.     delete[] num;  
  30.     num = NULL;  
  31.     system("pause");  
  32.     return 0;  
  33. }  
  34.   
  35. int HanXinCount(int *num)  
  36. {  
  37.     int persons = -1;  
  38.     for (int i = 10; i <= 100;i++)  
  39.     {  
  40.         if ( i%3==num[0] && i%5==num[1] && i%7==num[2])  
  41.         {  
  42.             persons = i;  
  43.         }  
  44.     }  
  45.     return persons;  
  46. }  


练习26,组合数

描述
找出从自然数1、2、... 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。
输入
输入n、r。
输出
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。
样例输入
5 3
样例输出
543
542
541
532
531
521
432
431
421
321

难度3,第32题

方法:

DFS法,深度遍历型程序设计


“组合数”代码实现如下:

  1. // ConsoleAppAcmTest32.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5.   
  6. #include "iostream"  
  7. using namespace std;  
  8.   
  9. int a[11];  
  10. bool visit[11];//存放数据被访问否  
  11.   
  12. void DFSCombiNum1(int n,int cur, int r);  
  13.   
  14. void printNum(int *w, int r);  
  15. int _tmain(int argc, _TCHAR* argv[])  
  16. {  
  17.     system("color 0A");  
  18.     int n = 5;  
  19.     int r = 3;  
  20.     cout << "确定范围1到n:请输入n的具体值"<<endl;  
  21.     cin >> n;  
  22.     while (n>10)  
  23.     {  
  24.         cout << "重新确定范围1到n:请输入n的具体值" << endl;  
  25.         cin >> n;  
  26.     }  
  27.   
  28.     cout << "从1到n取r个数:请输入r的具体值" << endl;  
  29.     cin >> r;  
  30.     while (r > n)  
  31.     {  
  32.         cout << "重新输入r" << endl;  
  33.         cin >> r;  
  34.     }  
  35.     memset(visit, false, sizeof(visit));//初始化  
  36.     DFSCombiNum1(n,1, r);  
  37.   
  38.     system("pause");  
  39.     return 0;  
  40. }  
  41.   
  42. //递归法DFS  
  43. void DFSCombiNum1(int n, int cur, int r) //入口、当前层、总层数    
  44. {  
  45.     if (cur > r) //结束条件    
  46.         return;  
  47.     for (int i = n; i >= 1; i--)//从n遍历到1,  
  48.     {  
  49.         if (!visit[i])//当前这个数没有被访问过,则访问他  
  50.         {  
  51.             visit[i] = true;  
  52.             a[cur] = i;//记录要输出的数字  
  53.             if (cur == r)//每次当cur增加到r时就输出放在a中的数  
  54.             {  
  55.                 printNum(a, r);  
  56.             }  
  57.   
  58.   
  59.             DFSCombiNum1(i - 1, cur + 1, r);  
  60.             visit[i] = false;  
  61.         }  
  62.     }  
  63. }  
  64.   
  65.   
  66. void printNum(int *a, int r)  
  67. {  
  68.     for (int i = 1; i <= r; i++)  
  69.     {  
  70.         cout << a[i];  
  71.     }  
  72.     cout << endl;  
  73. }  





练习27,计算超大数相乘:

编写两个超大数相乘,不用考虑负数

  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4. void Multiply(const string &a, const string &b, vector<int> &ansStr);  
  5. int main()  
  6. {  
  7.     string bigNum1, bigNum2;     // 初始状态用string来存储大数  
  8.     while (cin >> bigNum1 >> bigNum2)  
  9.     {  
  10.         vector<int> ans(bigNum1.size() + bigNum2.size(), 0);//接收答案,这里必须给予ans大小,否则传递参数时out of range  
  11.         Multiply(bigNum1, bigNum2, ans);  
  12.         for (unsigned int i = 1; i < ans.size(); i++)  
  13.                 cout << ans[i];  
  14.         cout << endl;  
  15.         ans.clear();  
  16.     }  
  17.     return 0;  
  18. }  
  19. void Multiply(const string &a, const string &b, vector<int> &ans)  
  20. {  
  21.     int lena = a.length(),lenb = b.length();  
  22.     for (int i = 0; i < lena; i++)  
  23.     {  
  24.         for (int j = 0; j < lenb; j++)  
  25.         {//25,a[0]=2,a[1]=5,31,b[0]=3,b[1]=1;推出==》ans[1]=6,ans[2]=17,ans[3]=5,(ans[0]=0)  
  26.             ans[i + j + 1] += (a[i] - '0')*(b[j] - '0');  
  27.         }}  
  28.       
  29.     for (int i = lena + lenb - 1; i >= 0; i--)// 这里实现进位操作  
  30.     {  
  31.         if (ans[i] >= 10)  
  32.         {  
  33.             ans[i - 1] += ans[i] / 10;//让高位获得来自低位的进位值,注意ans[i]相对ans[i-1]是低位  
  34.             ans[i] %= 10;//低位自裁,只保留当前数的个位即可,比如223,只保留3,22给高位  
  35.         }}}  



练习28,单词的部分逆置

举例;“I am  Chinese.”
逆置后为”Chinese. am I“

参考代码:

  1. #include "string"  
  2. #include "vector"  
  3.   
  4. #include <iostream>  
  5. using namespace std;  
  6.   
  7. int main()  
  8. {  
  9.   
  10.     string str;  
  11.     while (getline(cin,str))  
  12.     {  
  13.         //以此为例 "I am Chinese."  
  14.         int i = 0j = str.size() - 1;  
  15.         char temp;  
  16.         //逆置字符串,"esenihC. ma I"  
  17.         while (j > i)  
  18.         {  
  19.             temp = str[i];  
  20.             str[i] = str[j];  
  21.             str[j] = temp;  
  22.             i++; j--;  
  23.         }  
  24.         //部分反转,"Chinese. am I"  
  25.         int begin = 0end = 0;  
  26.         int ii = 0;  
  27.         while (ii < str.size())  
  28.         {  
  29.             if (str[ii] != ' ')//寻找空格前的子串  
  30.             {  
  31.                 begin = ii;   
  32.                 while (str[ii] != ' '&& ii < str.size())//这里考虑了在计数最后一个字符时的情况  
  33.                 {  
  34.                     ii++;  
  35.                 }  
  36.                 ii--;  
  37.                 end = ii;  
  38.             }  
  39.             while (end > begin)  
  40.             {  
  41.                 temp = str[begin];  
  42.                 str[begin++] = str[end];  
  43.                 str[end--] = temp;  
  44.             }  
  45.             ii++;  
  46.         }  
  47.   
  48.         cout << str << endl;  
  49.     }  
  50.     return 0;  
  51. }  


练习29,二分查找法存在的问题

PS:有的东西表面看上去公正、全面,实际可能走向极端的分立思维,许多客观事物不能简单均分,可能其内在具有复杂的联系,一旦坚持平分,结果倒失去了客观、全面的基础。

时间复杂度
折半搜索每次把搜索区域减少一半,时间复杂度为O\left( \log n  \right)。(n代表集合中元素的个数)
空间复杂度
O\left(  1  \right)。虽以递归形式定义,但是尾递归,可改写为循环


维基百科告诉我们要这样写:为什么呢?

  1. <span style="font-size:12px;">//递归版本  
  2. int binary_search( const int arr[], int low, int high, int key)  
  3. {  
  4.    int mid = low+(high-low)/2; // 别用 (low+high)/2 ,因为可能引起溢出问题。  
  5.    if(low>high)  
  6.        return -1;  
  7.    else  
  8.      {  
  9.        if(arr[mid]==key)  
  10.           return mid;  
  11.        else if(arr[mid]>key)  
  12.           return binary_search(arr,low,mid-1,key);  
  13.        else   
  14.           return binary_search(arr,mid+1,high,key);  
  15.      }  
  16. }</span>  

开始分析

一般二分法这样写:

  1. <span style="font-size:12px;">int binarySearch(int arr[], int l, int h, int key)  
  2. {  
  3.     while (l <= h)  
  4.     {  
  5.         // find index of middle element  
  6.         int m = (l+h)/2;  
  7.    
  8.         // Check if key is present at mid  
  9.         if (arr[m] == key) return m;  
  10.    
  11.         // If key greater, ignore left half  
  12.         if (arr[m] < key) l = m + 1;  
  13.    
  14.         // If key is smaller, ignore right half  
  15.         else h = m - 1;  
  16.     }  
  17.    
  18.     // if we reach here, then element was not present  
  19.     return -1;  
  20. }</span>  

以上看起来没事,除了一个很微妙的东西,表达“m =(l+r)/ 2″。它不能用于l和r特别大的时候,如果l和r的总和大于最大正int值(2的31次方–1)。将溢出为负值,即求和之后成了负值时,再除以2也是负值。这将导致索引超出范围不可预知的结果


所以解决这个问题的方法就是:

mid = ((unsigned int)low + (unsigned int)high)) >> 1 ;

或者

mid = low+(high-low)/2; 




练习30,显式的调用析构器和构造器

构造函数是一个很特殊的成员函数,当一个对象被创建时他将会自动被调用。析构器也是一个很特殊的成员函数,当对象在作用域结束时会被自动的隐式调用。当动态分配内存和销毁时也会调用这两个特殊的函数,即new和delete操作符!

进入正题,显式调用这两个特殊的函数:

  1. #include <iostream>  
  2. using namespace std;  
  3.    
  4. class Test  
  5. {  
  6. public:  
  7.     Test()  { cout << "Constructor is executed\n"; }  
  8.     ~Test() { cout << "Destructor is executed\n";  }  
  9. };  
  10.    
  11. int main()  
  12. {  
  13.     Test();  // 显式调用构造器  
  14.     Test t; // 创建本地对象  
  15.     t.~Test(); // 显式调用析构器  
  16.     return 0;  
  17. }  
  18. ///输出:  
  19.   
  20. Constructor is executed   (Test()显式调用产生的,同时会产生一个临时对象,并立刻销毁)  
  21. Destructor is executed    (临时对象造成的,此时析构器被调用)  
  22. Constructor is executed   (创建本地对象产生的)  
  23. Destructor is executed    (显式调用析构器产生的,但是并不意味着对象被销毁)  
  24. Destructor is executed    (main结束时,析构函数在对象t作用域的末尾调用,起到释放资源的作用)  

当构造器被显式调用时,编译器立刻创建了一个未命名的临时对象,同时它也被立刻销毁,这也是为什么输出中的第二行会是“析构器被执行”特别注意,如果对象时动态分配的内存,千万别显式调用析构器,因为delete会调用析构器。

类的成员函数也能调用析构器和构造器

  1. #include <iostream>  
  2. using namespace std;  
  3.    
  4. class Test  
  5. {  
  6. public:  
  7.     Test()  { cout << "Constructor is executed\n"; }  
  8.     ~Test() { cout << "Destructor is executed\n";  }  
  9.     void show()  {  Test();  this->Test::~Test();  }  
  10. };  
  11.    
  12. int main()  
  13. {  
  14.     Test t;  
  15.     t.show();  
  16.     return 0;  
  17. }  
  18. 输出:  
  19.   
  20. Constructor is executed  
  21. Constructor is executed  
  22. Destructor is executed  
  23. Destructor is executed  
  24. Destructor is executed  


最后再来分析一段程序:

  1. #include <iostream>  
  2. using namespace std;  
  3.    
  4. class Test  
  5. {  
  6. public:  
  7.     Test()  { cout << "+++"; }  
  8.     ~Test() { cout << "---";  }  
  9.     friend void fun(Test t);  
  10. };  
  11. void fun(Test t)  
  12. {  
  13.     Test();//析构器和构造器均会被调用  
  14.     t.~Test();//显式调用析构器............然后就完了吗?对象t在这个函数的末尾被自动在调用一次析构器!!!  
  15. }  
  16. int main()  
  17. {  
  18.     Test();//输出+++,然后---  
  19.     Test t;//输出+++  
  20.     fun(t);//输出+++,---,---,---  
  21.     return 0;//输出---  
  22. }  
所以输出为:

  1. +++  
  2. ---  
  3. +++  
  4. +++  
  5. ---  
  6. ---  
  7. ---  
  8. ---  

有时候显示调用析构器是有用的,微软告诉我们:

很少需要显式调用析构函数。 但是,对置于绝对地址的对象进行清理会很有用。 这些对象通常使用采用位置参数的用户定义的 new 运算符进行分配。 delete 运算符不能释放该内存,因为它不是从自由存储区分配的(有关详细信息,请参阅 new 和 delete 运算符)。 但是,对析构函数的调用可以执行相应的清理。 若要显式调用 String 类的对象 s 的析构函数,请使用下列语句之一:

s.String::~String();     // Nonvirtual call
ps->String::~String();   // Nonvirtual call

s.~String();       // Virtual call
ps->~String();     // Virtual call

可以使用对前面显示的析构函数的显式调用的表示法,无论类型是否定义了析构函数。 这允许您进行此类显式调用,而无需了解是否为此类型定义了析构函数。 显式调用析构函数,其中未定义的析构函数无效。



练习31,调整数组结构

模拟小波变换中LL,HL,LH,HH系数调整

  1. #include "iostream"   
  2. #include "windows.h"  
  3. #include "fstream"  
  4. #include "algorithm"   
  5.   
  6. using namespace wavelet;  
  7. using namespace std;  
  8.   
  9.   
  10. bool AdjustData(  
  11.     double *pDetCoef,  
  12.     const int height,  
  13.     const int width  
  14.     )  
  15. {  
  16.     if (pDetCoef == NULL)  
  17.         return false;  
  18.     double *ptmpdet = new double[height / 2 * width];  
  19.     for (int i = 0; i < height / 2 * width; i++)  
  20.         ptmpdet[i] = pDetCoef[i];  
  21.     int pos1 = 0;  
  22.     int pos2 = height / 2 * width / 2;  
  23.     for (int i = 0; i < height / 2; i++)  
  24.     {  
  25.         for (int j = 0; j < width; j++)  
  26.         {  
  27.             if (j < width / 2)  
  28.                 pDetCoef[pos1++] = ptmpdet[i*width + j];  
  29.             else  
  30.                 pDetCoef[pos2++] = ptmpdet[i*width + j];  
  31.         }  
  32.     }  
  33.     delete[] ptmpdet;  
  34.     ptmpdet = NULL;  
  35.     return true;  
  36. }  
  37.   
  38.   
  39. bool IAdjustData(  
  40.     double *pDetCoef,  
  41.     const int height,  
  42.     const int width  
  43.     )  
  44. {  
  45.     if (pDetCoef == NULL)  
  46.         return false;  
  47.   
  48.     double *ptmpdet = new double[height / 2 * width];  
  49.     for (int i = 0; i < height / 2 * width; i++)  
  50.         ptmpdet[i] = pDetCoef[i];  
  51.     int pos1 = 0;  
  52.     int pos2 = height / 2 * width / 2;  
  53.     for (int i = 0; i < height / 2; i++)  
  54.     {  
  55.         for (int j = 0; j < width; j++)  
  56.         {  
  57.             if (j < width / 2)  
  58.                 pDetCoef[i*width + j] = ptmpdet[pos1++];  
  59.             else  
  60.                 pDetCoef[i*width + j] = ptmpdet[pos2++];  
  61.         }  
  62.     }  
  63.       
  64.       
  65.     delete[] ptmpdet;  
  66.     ptmpdet = NULL;  
  67.   
  68.     return true;  
  69. }  
  70.   
  71. int main()  
  72. {  
  73.     system("color 0A");  
  74.     double s[30] = {1,2,3,4,5,6,  2,3,4,5,6,7,  3,4,5,6,7,8,  4,5,6,7,8,9, 5,6,7,8,9,10};  
  75.     int height = 5;  
  76.     int width = 6;  
  77.   
  78.     for (int i = 0; i < height; i++)  
  79.     {  
  80.         for (int j = 0; j < width; j++)  
  81.             cout << s[i*width + j] << " ";  
  82.         cout << endl;  
  83.     }  
  84.     cout << endl; cout << endl;  
  85.     AdjustData(s,height,width);  
  86.   
  87.     for (int i = 0; i < height; i++)  
  88.     {  
  89.         for (int j = 0; j < width; j++)  
  90.             cout << s[i*width + j] << " ";  
  91.         cout << endl;  
  92.     }  
  93.   
  94.     IAdjustData(s, height, width);  
  95.   
  96.     cout << endl; cout << endl;  
  97.     for (int i = 0; i < height; i++)  
  98.     {  
  99.         for (int j = 0; j < width; j++)  
  100.             cout << s[i*width + j] << " ";  
  101.         cout << endl;  
  102.     }  
  103.     system("pause");  
  104.     return 0;  
  105. }  




题源参考

【1】《编程之美》
【2】《 C++算法,妙趣横生》
【3】南阳理工OJ
【4】九度OJ
【5】维基百科
【6】C++primer

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值