增强的数学函数库(第1次发布,功能不断增加中)

  1 /*- ==========================================================
  2 *     文件名  :MathFunc.h
  3 *     开发人员:袁培荣
  4 *     当前版本:1.3.3.2595 (第1次发布,功能不断增加中)
  5 *     创建时间:2012-05-28
  6 *     修改时间:2012-05-30
  7 *     功能说明:增强的数学函数库的声明
  8 *     版权说明:版权所有 袁培荣 YuanPeirong 
  9 *     编译环境:Windows 7(x64) SP1 简体中文专业版
 10 *     编译器:  Visual Studio 2010 SP1(中文旗舰版)
 11                 MinGW 20120426 GNU GCC 4.6.2
 12                 Visual C++ 6.0 SP6(中文企业版)
 13 - ==========================================================*/
 14 
 15 //编译测试情况:
 16 // 1.Visual Studio 2010 SP1(中文旗舰版):
 17 //   在Release和Debug下都编译通过,测试运行正常。
 18 // 2.MinGW 20120426 GNU GCC 4.6.2:
 19 //   编译通过,测试运行正常。
 20 // 3.Visual C++ 6.0 SP6(中文企业版)
 21 //   未测试。
 22 
 23 #ifndef MathFunc_H_TYCppStdLib              //防止头文件重复包含
 24 #define MathFunc_H_TYCppStdLib
 25 
 26 #ifdef MathFunc_DLL_API                     //为导出DLL预留
 27 #else
 28 #define MathFunc_DLL_API _declspec(dllimport)
 29 #endif
 30 
 31 #include <cstdlib>
 32 #include <cmath>
 33 #include <ctime>
 34 #include <vector>     //vector容器
 35 #include <algorithm>  //泛型算法
 36 #include <numeric>    //泛化算法
 37 //#include <functional> //标准库的函数对象类型在此定义
 38 
 39 using namespace std;
 40 
 41 namespace TYCppStdLib   //所有功能都封装在命名空间TYCppStdLib中
 42 {
 43     //产生一个随机整数
 44     int Random(
 45         int minValue=-32768,      //设置数据的最大值(包含)
 46         int maxValue=32767,       //设置数据的最大值(包含)
 47         bool isPrime=false        //是否必须要返回质数
 48     );
 49     
 50     //产生随机纯小数
 51     double Random(
 52         double minValue=0,   //设置数据的最小值(包含)
 53         double maxValue=1,   //设置数据的最大值(包含)
 54         bool get0and1=false  //指明是否可以产生0和1
 55     );
 56     
 57     //产生一组随机整数(此函数是以前写的,将要被我弃用,因为使用了不安全的数组)
 58     //建议使用功能更加强大的 RandomVecInt函数(在下文中定义)
 59     bool Random(
 60         int *data,           //用于存放产生的整数的数组首地址 
 61         int num,             //设置要产生的数据个数
 62         int minValue=-32768, //设置数据的最小值(包含)
 63         int maxValue=32767,  //设置数据的最大值(包含)
 64         bool different=false //设置数据是否要互不相同
 65     );
 66     
 67     //为Random函数定义相应的类,方便生成函数对象作为泛型算法的发生器
 68     class Random_cls
 69     {
 70     private:
 71         int minValue;
 72         int maxValue;
 73         bool isPrime;
 74     public:
 75         Random_cls(int min, int max, bool isp);
 76         int operator()();
 77     };
 78     
 79     bool IsPrime(int n);               //判断质数
 80     //获取n以内(含n)的所有质数的个数
 81     int GetPrime(int n);                 
 82     //获取n以内(含n)的所有质数,并返回质数的个数
 83     int GetPrime(int n, vector<int> &vec); 
 84     //int GetPrime(int n, int *p); //数组版本,因不安全,不想支持    
 85     bool IsSquare(int n);              //判断完全平方数
 86     
 87     //求两个数的最大公约数
 88     int GetGCD(int m, int n);
 89     //求一组数据的最大公约数(不安全,不推荐使用)
 90     int GetGCD(const int *p, int count); 
 91     //或者是int GetGCD(const int p[], int count);
 92     //求一组数据的最大公约数(安全,推荐使用)
 93     int GetGCD(vector<int> &vec);
 94     
 95     //求两个数的最小公倍数
 96     int GetLCM(int m, int n);
 97     //求一组数据的最小公倍数(不安全,不推荐使用)
 98     int GetLCM(const int *p, int count);
 99     //或者是int GetLCM(const int p[], int count);
100     //求一组数据的最小公倍数(安全,推荐使用)
101     int GetLCM(vector<int> &vec);
102     
103     int GetFactorial(int n);  //求阶乘(13以内)(非递归和递归方式实现)
104     //获得0到n的阶乘结果(n超过13时设为13)
105     //这里不用到GetFactorial,因为效率太低
106     void FacVecInt(vector<int> &vec, int n);    
107     
108     int InversionData(int n); //求整数的逆序数,如6589返回9856
109     
110     //以下用到 vector 的函数都可以写相应的数组版本
111     //但是因为数组是不安全的东西,不想再支持数组
112     
113     //获取数字的位数
114     int DivideDigit(int n);
115     //获取数字的各个位上的数值,并返回分离出的数字个数
116     int DivideDigit(
117         int n,               //待求数字
118         vector<int> &vec,    //存储结果
119         bool forward=true    //ture:高位在前存储,false:低位在前存储
120     );
121     //获取数字的各个位上的数值(高位在前),并返回分离出的数字个数
122     //int DivideDigitA(int n, vector<int> &vec); //不再需要
123     //获取数字的各个位上的数值(低位在前),并返回分离出的数字个数
124     //int DivideDigitB(int n, vector<int> &vec); //不再需要
125     
126     //将一组数据按位合成一个数
127     int JoinDigit(
128         const vector<int> &vec, //一组数据
129         bool forward=true,      //ture:高位在前,false:低位在前
130         bool onlyBit=false      //数据中的每一位是否只取其个位
131     );
132     
133     //生成一组随机数据(用随机数据初始化vector<int>)
134     void RandomVecInt(
135         vector<int> &vec,      //存放数据的容器
136         int num,               //产生数据的个数
137         int minValue=-32768,   //设置数据的最大值(包含)
138         int maxValue=32767,    //设置数据的最大值(包含)
139         bool isPrime=false     //产生的数据是否必须为质数
140     );
141     
142     //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(非递归和递归方式实现)
143     int Fibonacci(int n);
144     //求Fibonacci数列的前N项(用Fibonacci数列初始化vector<int>)
145     //这里不用到Fibonacci函数,因为效率太低
146     void FibVecInt(vector<int> &vec, int num); 
147     
148     //求一组数据的和
149     template<typename T>
150     T GetSum(const vector<T> &vec);
151     // template<typename T> //初始实现版本
152     // T GetSum(typename vector<T>::const_iterator start, typename vector<T>::const_iterator end);
153     //调用方式:T sum=GetSum(s, e)或者 GetSum<T>(s, e)
154     template<typename T, typename InputIterator> //更加泛化的实现版本
155     T GetSum(InputIterator start, InputIterator end);
156     //调用方式:T sum=GetSum(s, e)或者 GetSum<T>(s, e)
157     
158     //求一组数据的算术平均数(涉及到除法,因此返回值转为double,下同)
159     template<typename T>
160     double GetMean(const vector<T> &vec);
161     
162     //求一组数据的方差
163     template<typename T>
164     double GetVariance(const vector<T> &vec);
165 
166     //求一组数据的标准差
167     template<typename T>
168     double GetStDev(const vector<T> &vec);
169     
170     //将一组数据反序,并覆盖原数据
171     template<typename T>
172     void InverseVec(vector<T> &vec); //结果覆盖原数据
173     //将一组数据反序,不覆盖原数据
174     template<typename T>
175     void InverseVec(
176         const vector<T> &vec1,      //原数据
177         vector<T> &vec2             //逆序数据
178     );
179     
180     //比较两个数的大小
181     template<typename T>
182     bool IsBig(const T &m, const T &n);
183     template<typename T>
184     bool IsSmall(const T &m, const T &n);
185     
186     //将一组数据进行排序,并覆盖原数据
187     template<typename T>
188     void SortVec(
189         vector<T> &vec,        //结果覆盖原数据
190         bool smallToBig=true,  //ture:从小到大,false:从大到小
191         bool eraseUnique=false //ture:去除重复值,false:不去除重复值
192     ); 
193     //将一组数据进行排序,不覆盖原数据
194     template<typename T>
195     void SortVec(
196         const vector<T> &vec1, //原数据
197         vector<T> &vec2,       //逆序数据
198         bool smallToBig=true,  //ture:从小到大,false:从大到小
199         bool eraseUnique=false //ture:去除重复值,false:不去除重复值
200     );
201     
202     //生成等差数列(Arithmetic Sequence)(用等差数列初始化vector<T>)
203     template<typename T>
204     void AriVecT(
205         vector<T> &vec, //存储数据
206         T fisrt,        //首项
207         T tolerance,    //公差
208         T num           //项数
209     );
210     
211     //生成等比数列(Geometric Sequence)(用等比数列初始化vector<T>)
212     template<typename T>
213     void GeoVecT(
214         vector<T> &vec, //存储数据
215         T fisrt,        //首项
216         T comRatio,     //公比
217         T num           //项数
218     );
219     
220     // 仅为测试
221     // template<typename T>
222     // T GetTest(T n);
223 
224 }
225 
226 //为了兼容各编译器,特别是VC++6.0这种低级的旧版本编译器
227 //只好采用模板的包含编译模式
228 //模板的实现放在.hpp文件中,编译时不单独编译
229 //而事实上, Visual Studio 2010也不能采用更先进的分离编译模式
230 //而对C++标准支持得最好的MinGW也不能支持更先进的分离编译模式
231 //除了国外极少数的冷门商业编译器支持分离编译模式
232 //我现有的编译器都不只支持,因此只能头文件反向包含源文件的做法
233 //采用了boost的做法,将其反缀名定为 .hpp ,即 .h + .cpp
234 #include "MathFunc.hpp" 
235 //在编译时,应将此hpp文件当做头文件而非源文件,即不单独编译
236 #endif
237 
238 //摘自:SGI STL
239 /*   template<typename _InputIterator, typename _Tp>
240     inline _Tp
241     accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
242     {
243       // concept requirements
244       __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
245       __glibcxx_requires_valid_range(__first, __last);
246 
247       for (; __first != __last; ++__first)
248     __init = __init + *__first;
249       return __init;
250     } */
  1 /*- ==========================================================
  2 *     文件名  :MathFunc.cpp
  3 *     开发人员:袁培荣
  4 *     当前版本:1.3.3.2595 (第1次发布,功能不断增加中)
  5 *     创建时间:2012-05-28
  6 *     修改时间:2012-05-30
  7 *     功能说明:增强的数学函数库的实现
  8 *     版权说明:版权所有 袁培荣 YuanPeirong 
  9 *     编译环境:Windows 7(x64) SP1 简体中文专业版
 10 *     编译器:  Visual Studio 2010 SP1(中文旗舰版)
 11                 MinGW 20120426 GNU GCC 4.6.2
 12                 Visual C++ 6.0 SP6(中文企业版)
 13 - ==========================================================*/
 14 
 15 //编译测试情况:
 16 // 1.Visual Studio 2010 SP1(中文旗舰版):
 17 //   在Release和Debug下都编译通过,测试运行正常。
 18 // 2.MinGW 20120426 GNU GCC 4.6.2:
 19 //   编译通过,测试运行正常。
 20 // 3.Visual C++ 6.0 SP6(中文企业版)
 21 //   未测试。
 22 
 23 #ifndef MathFunc_DLL_ForAPI
 24 #define MathFunc_DLL_ForAPI
 25 
 26 #define MathFunc_DLL_API _declspec(dllexport) //为导出DLL预留
 27 
 28 #endif
 29 
 30 #include "../Include/MathFunc.h"
 31 
 32 using namespace std;
 33 using namespace TYCppStdLib;
 34 
 35 //产生一个随机整数
 36 int TYCppStdLib::Random(
 37     int minValue,        //设置数据的最大值(包含)
 38     int maxValue,        //设置数据的最大值(包含)
 39     bool isPrime         //是否必须要返回质数
 40 )
 41 {
 42     if(maxValue<minValue)
 43         return 0;//return false;
 44     if(minValue<-32768)
 45         minValue=-32768;
 46     if(maxValue>32767)
 47         maxValue=32767;
 48     int ix;
 49     static bool randomFisrt=true;
 50     if(randomFisrt)
 51         srand(time(static_cast<time_t>(0)));
 52     randomFisrt=false;
 53     ix=rand();
 54     ix=ix%(maxValue-minValue+1)+minValue;
 55     if(!isPrime)
 56         return ix;
 57     bool isp=IsPrime(ix);
 58     if(isp)
 59         return ix;
 60     while(!isp)
 61     {
 62         ix=rand();
 63         ix=ix%(maxValue-minValue+1)+minValue;
 64         isp=IsPrime(ix);
 65     }
 66     return ix;
 67 }
 68 
 69 //产生随机纯小数
 70 double TYCppStdLib::Random(double minValue, double maxValue, bool get0and1)
 71 {
 72     if(maxValue<minValue)
 73         return 0;//return false;
 74     if(minValue<0)
 75         minValue=0;
 76     if(maxValue>1)
 77         maxValue=1;
 78     double dx;
 79     int ix1, ix2;
 80     ix1=(int)(minValue*32767);
 81     ix2=(int)(maxValue*32767);
 82     ix1=Random(ix1, ix2);
 83     if(false==get0and1 && 0==minValue && 1==maxValue)
 84     {
 85         if(!ix1)
 86             ix1=1;
 87         if(ix1==32767)
 88             ix1=32766;
 89     }
 90     dx=(double)(ix1)/32767;
 91     return dx;
 92 }
 93 
 94 //产生一组随机整数(此函数是以前写的,将要被我弃用,因为使用了不安全的数组)
 95 bool TYCppStdLib::Random(int *data, int num, int minValue, int maxValue, bool different)
 96 {
 97 
 98     if(num<1 || maxValue<minValue)
 99         return false;
100     if(minValue<-32768)
101         minValue=-32768;
102     if(maxValue>32767)
103         maxValue=32767;
104     if(different && (maxValue-minValue+1)<num)
105         return false;
106     int ii, ij, ix;
107     for(ii=0;ii<num;ii++)
108     {
109         while(1)
110         {
111             ix=Random(minValue, maxValue);
112             if(!different)
113                 break;
114             for(ij=0;ij<ii;ij++)
115             {
116                 if(ix==*(data+ij))
117                     break;
118             }
119             if(ij==ii)
120                 break;
121         }
122         *(data+ii)=ix;
123     }
124     return true;
125 }
126 
127 //以下的函数是正确的,只是将数组形参写成指针形式更好,因此弃用
128 // 产生一批随机整数
129 // bool Random(
130     // int data[], //用于存放产生的整数的数组
131     // int num,    //设置要产生的数据个数
132     // int minValue=-32768, //设置数据的最小值(包含)
133     // int maxValue=32767,//设置数据的最大值(包含)
134     // bool different=false //设置数据是否要互不相同
135 // );
136 
137 // bool Random(int data[], int num, int minValue, int maxValue, bool different)
138 // {
139 
140     // if(num<1 || maxValue<minValue)
141         // return false;
142     // if(minValue<-32768)
143         // minValue=-32768;
144     // if(maxValue>32767)
145         // maxValue=32767;
146     // if(different && (maxValue-minValue+1)<num)
147         // return false;
148     // int ii, ij=0, ix;
149     // for(ii=0;ii<num;ii++)
150     // {
151         // while(1)
152         // {
153             // ix=Random(minValue, maxValue);
154             // if(!different)
155                 // break;
156             // for(ij=0;ij<ii;ij++)
157             // {
158                 // if(ix==data[ij])
159                     // break;
160             // }
161             // if(ij==ii)
162                 // break;
163         // }
164         // data[ii]=ix;
165     // }
166     // return true;
167 // }
168 
169 //为Random函数定义相应的类,方便生成函数对象作为泛型算法的发生器
170 TYCppStdLib::Random_cls::Random_cls(int min, int max, bool isp)
171 {
172     minValue=min;
173     maxValue=max;
174     isPrime=isp;
175 }
176 
177 int TYCppStdLib::Random_cls::operator()()
178 {
179     return Random(minValue, maxValue, isPrime);    
180 }
181 
182 //判断质数
183 bool TYCppStdLib::IsPrime(int n)
184 {
185     n=abs(n); //允许n是负数
186     if(n<2)
187         return false;
188     int m=static_cast<int>(sqrt(static_cast<double>(n)))+1;
189     for(int i=2; i<m+1; i++) //i<m或i<m+1
190         if(n%i==0)
191             return false;
192     return true;
193 }
194 
195 //获取n以内(含n)的所有质数的个数
196 int TYCppStdLib::GetPrime(int n)
197 {
198     if(n<2)
199         return 0;
200     if(2==n)
201         return 1;
202     int num=1;
203     for(int i=3; i<=n; i=i+2)
204         if(IsPrime(i))
205             num++;
206     return num;
207 }  
208 
209 //获取n以内(含n)的所有质数,并返回质数的个数
210 int TYCppStdLib::GetPrime(int n, vector<int> &vec)
211 {
212     vec.clear();
213     if(n<2)
214         return 0;
215     if(2==n)
216     {
217         vec.push_back(2);
218         return 1;
219     }
220     vec.push_back(2);
221     for(int i=3; i<=n; i=i+2)
222         if(IsPrime(i))
223             vec.push_back(i);
224     return static_cast<int>(vec.size());
225 }
226 
227 //判断完全平方数
228 bool TYCppStdLib::IsSquare(int n) 
229 {
230     if(n<0)
231         return false;
232     int m=static_cast<int>(sqrt(static_cast<double>(n)));
233     if(m*m==n)
234         return true;
235     return false;
236 }
237 
238 //求两个数的最大公约数
239 int TYCppStdLib::GetGCD(int m, int n)
240 {
241     if(!m && !n)
242         return 0;
243     if(!m)
244         return n;
245     if(!n)
246         return m;
247     int r;
248     while(r=m%n)
249     {
250         m=n;
251         n=r;
252     }
253     return abs(n);
254 }
255 
256 //求一组数据的最大公约数(不安全,不推荐使用)
257 int TYCppStdLib::GetGCD(const int *p, int count)
258 { 
259     if(!p || count<2)  
260         return 0;
261     int gcd=p[0]; 
262     for(int i=1; i!=count; i++)
263         gcd=GetGCD(gcd,p[i]);
264     return abs(gcd);
265 }
266 
267 //求一组数据的最大公约数(安全,推荐使用)
268 int TYCppStdLib::GetGCD(vector<int> &vec)
269 {
270     int vsize=vec.size();
271     if(vsize<2)
272         return 0;
273     int gcd=vec[0];
274     for(int i=1; i!=vsize; i++)
275         gcd=GetGCD(gcd, vec[i]);
276     return abs(gcd);
277 }
278 
279 //求两个数的最小公倍数
280 int TYCppStdLib::GetLCM(int m, int n) 
281 {
282     if(!m || !n)
283         return 0;
284     int lcm=m*n/GetGCD(m, n); //GetGCD(m, n)不会再返回0
285     return abs(lcm);          //因为返回0的情况在前面已经排除
286 }
287 
288 //求一组数据的最小公倍数(不安全,不推荐使用)
289 int TYCppStdLib::GetLCM(const int *p, int count)
290 { 
291     if(!p || count<2)
292         return 0;
293     int lcm=p[0];
294     for(int i=1; i!=count; i++)
295         lcm=GetLCM(lcm, p[i]);
296     return abs(lcm);
297 }
298 
299 //求一组数据的最小公倍数(安全,推荐使用)
300 int TYCppStdLib::GetLCM(vector<int> &vec)
301 {
302     int vsize=vec.size();
303     if(vsize<2)
304         return 0;
305     int lcm=vec[0];
306     for(int i=1; i!=vsize; i++)
307         lcm=GetLCM(lcm, vec[i]);
308     return abs(lcm);
309 }
310 
311 //求阶乘(13以内)(非递归)
312 int TYCppStdLib::GetFactorial(int n)
313 {
314     if(n<0 || n>13)
315         return 0;
316     if(n<2)
317         return 1;
318     int fac=1;
319     for(int i=2; i<=n; i++)
320         fac=fac*i;
321     return fac;
322 }
323 
324 //以下为求阶乘的递归实现,两种方法效率几乎相同
325 //但为减小函数重复调用开销,选择非递归方式
326 
327 //求阶乘(13以内)(递归)
328 // int TYCppStdLib::GetFactorial(int n)
329 // {
330     // if(n<0 || n>13)
331         // return 0;
332     // if(n<2)
333         // return 1;
334     // return GetFactorial(n-1)*n;
335 // }
336 
337 //获得0到n的阶乘结果(n超过13时设为13)
338 //这里不用到GetFactorial,因为效率太低
339 void TYCppStdLib::FacVecInt(vector<int> &vec, int n)
340 {
341     vec.clear();
342     if(n<0)
343         return;
344     vec.push_back(1);
345     if(0==n)
346         return;
347     vec.push_back(1);
348     if(1==n)
349         return;
350     if(n>13)
351         n=13;
352     int fac=1;
353     for(int i=1; i!=n; i++)
354     {
355         fac=fac*(i+1);
356         vec.push_back(fac);
357     }
358 }
359 
360 //求整数的逆序数,如6589返回9856
361 int TYCppStdLib::InversionData(int n)
362 {
363     int s=0;
364     while(n)
365     {
366         s=10*s+n%10;
367         n=n/10;
368     }
369     return s;
370 }
371 
372 //获取数字的位数
373 int TYCppStdLib::DivideDigit(int n)
374 {
375     n=abs(n);
376     if(0==n)
377         return 1;
378     int num=0;
379     while(n)
380     {
381         n=n/10;
382         num++;
383     }
384     return num;
385 }
386 
387 //获取数字的各个位上的数值,并返回分离出的数字个数
388 int TYCppStdLib::DivideDigit(
389     int n,               //待求数字
390     vector<int> &vec,    //存储结果
391     bool forward         //ture:高位在前存储,false:低位在前存储
392 )
393 {
394     n=abs(n);
395     vec.clear();
396     int num=0;
397     if(0==n)
398     {
399         vec.push_back(0);
400         return 1;
401     }
402     if(forward)
403     {
404         while(n)
405         {
406             vec.insert(vec.begin(), n%10);
407             n=n/10;
408             num++;
409         }
410     }
411     else
412     {
413         while(n)
414         {
415             vec.push_back(n%10);
416             n=n/10;
417             num++;
418         }
419     }
420     return num;
421 }
422 
423 //以下两个函数的功能已经被集成到上面的函数中
424 
425 //获取数字的各个位上的数值(高位在前),并返回分离出的数字个数
426 // int TYCppStdLib::DivideDigitA(int n, vector<int> &vec)
427 // {
428     // n=abs(n);
429     // vec.clear();
430     // if(0==n)
431     // {
432         // vec.push_back(0);
433         // return 1;
434     // }
435     // int num=0;
436     // while(n)
437     // {
438         // vec.insert(vec.begin(), n%10);
439         // n=n/10;
440         // num++;
441     // }
442     // return num;
443 // }
444 
445 //获取数字的各个位上的数值(低位在前),并返回分离出的数字个数
446 // int TYCppStdLib::DivideDigitB(int n, vector<int> &vec)
447 // {
448     // n=abs(n);
449     // vec.clear();
450     // if(0==n)
451     // {
452         // vec.push_back(0);
453         // return 1;
454     // }
455     // int num=0;
456     // while(n)
457     // {
458         // vec.push_back(n%10);
459         // n=n/10;
460         // num++;
461     // }
462     // return num;
463 // }
464 
465 //将一组数据按位合成一个数
466 int TYCppStdLib::JoinDigit(
467         const vector<int> &vec, //一组数据
468         bool forward,           //ture:高位在前,false:低位在前
469         bool onlyBit            //数据中的每一位是否只取其个位
470 )
471 {
472     if(vec.empty())
473         return 0;
474     int sum=0;
475     vector<int>::size_type si;
476     if(forward)
477     {
478         for(si=0; si!=vec.size(); si++)
479         {
480             if(onlyBit)
481                 sum=sum*10+(vec[si]%10);
482             else
483                 sum=sum*10+vec[si];
484         }
485     }
486     else
487     {
488         for(si=vec.size()-1; si!=-1; si--)
489         {
490             if(onlyBit)
491                 sum=sum*10+(vec[si]%10);
492             else
493                 sum=sum*10+vec[si];
494         }
495     }
496     return sum;
497 }
498 
499 //生成一组随机数据(用随机数据初始化vector<int>)
500 void TYCppStdLib::RandomVecInt(
501     vector<int> &vec,      //存放数据的容器
502     int num,               //产生数据的个数
503     int minValue,          //设置数据的最大值(包含)
504     int maxValue,          //设置数据的最大值(包含)
505     bool isPrime           //产生的数据是否必须为质数
506 )
507 {
508     vec.clear();
509     if (num<1)
510         return;
511     vec.resize(num);
512     generate(vec.begin(), vec.end(), 
513              Random_cls(minValue, maxValue, isPrime));
514     return;
515 }
516 
517 //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(非递归)
518 int TYCppStdLib::Fibonacci(int n)
519 {
520     if(n<1)
521         return 0;
522     if(1==n || 2==n)
523         return 1;
524     int fib;
525     int n_1=1;
526     int n_2=1;
527     for(int i=2; i!=n; i++)
528     {
529         fib=n_1+n_2;
530         n_2=n_1;
531         n_1=fib;
532     }
533     return fib;
534 }
535 
536 //以下为求Fibonacci数列的第N项的递归实现,两种方法效率几乎相同
537 //但为减小函数重复调用开销,选择非递归方式
538 
539 //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(递归)
540 // int TYCppStdLib::Fibonacci(int n)
541 // {
542     // if(n<1)
543         // return 0;
544     // if(1==n || 2==n)
545         // return 1;
546     // return (Fibonacci(n-1)+Fibonacci(n-2));
547 // }
548 
549 //求Fibonacci数列的前N项(用Fibonacci数列初始化vector<int>)
550 //这里不用到Fibonacci函数,因为效率太低
551 void TYCppStdLib::FibVecInt(vector<int> &vec, int num)
552 {
553     vec.clear();
554     if(num<1)
555         return;
556     vec.push_back(1);
557     if(1==num)
558         return;
559     vec.push_back(1);
560     if(2==num)
561         return;
562     int n;
563     int n_1=1;
564     int n_2=1;
565     for(int i=2; i!=num; i++)
566     {
567         n=n_1+n_2;
568         vec.push_back(n);
569         n_2=n_1;
570         n_1=n;
571     }
572 }
573 
574 // 仅为测试
575 // template<typename T>
576 // T TYCppStdLib::GetTest(T n)
577 // {
578     // return (-n);
579 // }
  1 /*- ==========================================================
  2 *     文件名  :MathFunc.hpp
  3 *     开发人员:袁培荣
  4 *     当前版本:1.3.3.2595 (第1次发布,功能不断增加中)
  5 *     创建时间:2012-05-28
  6 *     修改时间:2012-05-30
  7 *     功能说明:增强的数学函数库的模板实现
  8 *     版权说明:版权所有 袁培荣 YuanPeirong 
  9 *     编译环境:Windows 7(x64) SP1 简体中文专业版
 10 *     编译器:  Visual Studio 2010 SP1(中文旗舰版)
 11                 MinGW 20120426 GNU GCC 4.6.2
 12                 Visual C++ 6.0 SP6(中文企业版)
 13 - ==========================================================*/
 14 
 15 //编译测试情况:
 16 // 1.Visual Studio 2010 SP1(中文旗舰版):
 17 //   在Release和Debug下都编译通过,测试运行正常。
 18 // 2.MinGW 20120426 GNU GCC 4.6.2:
 19 //   编译通过,测试运行正常。
 20 // 3.Visual C++ 6.0 SP6(中文企业版)
 21 //   未测试。
 22 
 23 #ifndef MathFunc_HPP_TYCppStdLib  //防止头文件重复包含
 24 #define MathFunc_HPP_TYCppStdLib
 25 
 26 #include <iostream>
 27 //求一组数据的和
 28 //export template<typename T>
 29 template<typename T>
 30 T TYCppStdLib::GetSum(const vector<T> &vec)
 31 {
 32     T sum=accumulate(vec.begin(), vec.end(), static_cast<T>(0));
 33     return sum;
 34 }
 35 
 36 //初始实现版本
 37 // template<typename T>
 38 // T TYCppStdLib::GetSum(
 39       // typename vector<T>::const_iterator start
 40     // , typename vector<T>::const_iterator end
 41 // )
 42 // {
 43     // T sum=accumulate(start, end, static_cast<T>(0));
 44     // return sum;
 45 // }
 46 
 47 //更加泛化的实现版本
 48 template<typename T, typename InputIterator>
 49 T TYCppStdLib::GetSum(InputIterator start, InputIterator end)
 50 {
 51     T sum=accumulate(start, end, static_cast<T>(0));
 52     return sum;
 53 }
 54 
 55 //求一组数据的算术平均数(涉及到除法,因此返回值转为double,下同)
 56 template<typename T>
 57 double TYCppStdLib::GetMean(const vector<T> &vec)
 58 {
 59     int num=static_cast<int>(vec.size());
 60     if(0==num)
 61         return static_cast<double>(0);
 62     T sum=accumulate(vec.begin(), vec.end(), static_cast<T>(0));
 63     return (static_cast<double>(sum))/(static_cast<double>(num));
 64 }
 65 
 66 //求一组数据的方差(第1正确实现版本)
 67 // template<typename T>
 68 // double TYCppStdLib::GetVariance(const vector<T> &vec)
 69 // {
 70     // double mean=GetMean(vec);
 71     // vector<double> temp;
 72     // for(vector<double>::size_type si=0; si!=vec.size(); si++)
 73     // {                                            // vec为空也不会出错
 74         // double vsi=static_cast<double>(vec[si]);
 75         // temp.push_back((vsi-mean)*(vsi-mean));
 76     // }
 77     // return GetMean(temp);
 78 // }
 79 
 80 //求一组数据的方差(优化实现版本)
 81 //===
 82 //优化原因:
 83 // 1.避免构造临时vector,
 84 // 2.避免调用外部函数对临时vector的遍历
 85 // 3.减少外部函数的调用次数
 86 // 4.更快的处理空数据
 87 // 5.减少内存占用
 88 //===
 89 template<typename T>
 90 double TYCppStdLib::GetVariance(const vector<T> &vec)
 91 {
 92     int num=static_cast<int>(vec.size());
 93     if(0==num)
 94         return static_cast<double>(0);
 95     double mean=GetMean(vec);
 96     double sum=0;             //sum和平均数有关,而平均数已经是double了
 97     for(vector<double>::size_type si=0; si!=vec.size(); si++)
 98     {
 99         double vsi=static_cast<double>(vec[si]);
100         sum=sum+((vsi-mean)*(vsi-mean));
101     }
102     return sum/(static_cast<double>(num));
103 }
104 
105 
106 //求一组数据的标准差
107 template<typename T>
108 double TYCppStdLib::GetStDev(const vector<T> &vec)
109 {
110     return sqrt(GetVariance(vec));
111 }
112 
113 //将一组数据反序,并覆盖原数据
114 template<typename T>
115 void TYCppStdLib::InverseVec(vector<T> &vec)  //结果覆盖原数据
116 {
117     vector<T> vec2;
118     for(typename vector<T>::size_type si=0; si!=vec.size(); si++)
119         vec2.insert(vec2.begin(), vec[si]);
120     vec=vec2;
121     return;
122 }
123 
124 //将一组数据反序,不覆盖原数据
125 template<typename T>
126 void TYCppStdLib::InverseVec(
127     const vector<T> &vec1,     //原数据
128     vector<T> &vec2            //逆序数据
129 )
130 {
131     vec2.clear();
132     for(typename vector<T>::size_type si=0; si!=vec1.size(); si++)
133         vec2.insert(vec2.begin(), vec1[si]);
134     return;
135 }
136 
137 //比较两个数的大小
138 template<typename T>
139 bool TYCppStdLib::IsBig(const T &m, const T &n)
140 {
141     return m>=n;
142 }
143 template<typename T>
144 bool TYCppStdLib::IsSmall(const T &m, const T &n)
145 {
146     return m<n;
147 }
148 
149 //将一组数据进行排序,并覆盖原数据
150 template<typename T>
151 void TYCppStdLib::SortVec(
152     vector<T> &vec,        //结果覆盖原数据
153     bool smallToBig,       //ture:从小到大,false:从大到小
154     bool eraseUnique       //ture:去除重复值,false:不去除重复值
155 )
156 {
157     if(smallToBig)
158         sort(vec.begin(), vec.end(), IsSmall<T>); //标准库有less和less_equal
159         //也可以写成sort(vec.begin(), vec.end());
160         //但在MinGW和VS2010的Release下编译通过,运行正常
161         //VS2010的Debug下编译通过,运行错误
162         //但写成sort(vec.begin(), vec.end(), IsSmall<T>);
163         //在MinGW和VS2010的Release,Debug下都编译通过而运行正常
164     else
165         sort(vec.begin(), vec.end(), IsBig<T>); //标准库有greater和greater_equal
166     if(eraseUnique)
167     {
168         typename vector<T>::iterator end_unique=
169             unique(vec.begin(), vec.end());
170         vec.erase(end_unique, vec.end());
171     }
172 }
173 //将一组数据进行排序,不覆盖原数据
174 template<typename T>
175 void TYCppStdLib::SortVec(
176     const vector<T> &vec1,   //原数据
177     vector<T> &vec2,         //逆序数据
178     bool smallToBig,         //ture:从小到大,false:从大到小
179     bool eraseUnique         //ture:去除重复值,false:不去除重复值
180 )
181 {
182     vec2=vec1;
183     SortVec(vec2, smallToBig, eraseUnique);
184 }
185 
186 //生成等差数列(Arithmetic Sequence)(用等差数列初始化vector<T>)
187 template<typename T>
188 void TYCppStdLib::AriVecT(
189     vector<T> &vec, //存储数据
190     T fisrt,        //首项
191     T tolerance,    //公差
192     T num           //项数
193 )
194 {
195     vec.clear();
196     if(num<1)
197         return;
198     for(int i=0; i!=num; i++)
199     {
200         vec.push_back(fisrt);
201         fisrt=fisrt+tolerance;
202     }
203 }
204 
205 //生成等比数列(Geometric Sequence)(用等比数列初始化vector<T>)
206 template<typename T>
207 void TYCppStdLib::GeoVecT(
208     vector<T> &vec, //存储数据
209     T fisrt,        //首项
210     T comRatio,     //公比
211     T num           //项数
212 )
213 {
214     vec.clear();
215     if(num<1)
216         return;
217     for(int i=0; i!=num; i++)
218     {
219         vec.push_back(fisrt);
220         fisrt=fisrt*comRatio;
221     }
222 }
223 
224 #endif
  1 /*- ==========================================================
  2 *     文件名  :test1.cpp
  3 *     开发人员:袁培荣
  4 *     当前版本:1.3.3.2595 (第1次发布,功能不断增加中)
  5 *     创建时间:2012-05-28
  6 *     修改时间:2012-05-30
  7 *     功能说明:增强的数学函数库的测试代码
  8 *     版权说明:版权所有 袁培荣 YuanPeirong 
  9 *     编译环境:Windows 7(x64) SP1 简体中文专业版
 10 *     编译器:  Visual Studio 2010 SP1(中文旗舰版)
 11                 MinGW 20120426 GNU GCC 4.6.2
 12                 Visual C++ 6.0 SP6(中文企业版)
 13 - ==========================================================*/
 14 
 15 //编译测试情况:
 16 // 1.Visual Studio 2010 SP1(中文旗舰版):
 17 //   在Release和Debug下都编译通过,测试运行正常。
 18 // 2.MinGW 20120426 GNU GCC 4.6.2:
 19 //   编译通过,测试运行正常。
 20 // 3.Visual C++ 6.0 SP6(中文企业版)
 21 //   未测试。
 22 
 23 #include <iostream>
 24 #include "../Include/MathFunc.h"
 25 //#include <vector>  //MathFunc.h中已经包含此头文件
 26 
 27 
 28 using namespace std;
 29 using namespace TYCppStdLib;
 30 
 31 template<typename T> //仅为方便输出容器的每一项
 32 void CoutVecT(const vector<T> &vec);
 33 
 34 int main(int argc, char* argv[])
 35 {
 36     if(IsPrime(5))
 37         cout<<"5是质数"<<endl;
 38     else
 39         cout<<"5不是质数"<<endl;
 40         
 41     if(IsPrime(9))
 42         cout<<"9是质数"<<endl;
 43     else
 44         cout<<"9不是质数"<<endl;
 45         
 46     if(IsSquare(5))
 47         cout<<"5是完全平方数"<<endl;
 48     else
 49         cout<<"5不是完全平方数"<<endl;
 50         
 51     if(IsSquare(9))
 52         cout<<"9是完全平方数"<<endl;
 53     else
 54         cout<<"9不是完全平方数"<<endl;
 55     
 56     cout<<"27和18的最大公约数是:"<<GetGCD(27, 18)<<endl;
 57     cout<<"27和18的最小公倍数是:"<<GetLCM(27, 18)<<endl;
 58     
 59     int arr[5]={6,9,36,18,72};
 60     cout<<"数组arr的最大公约数是:"<<GetGCD(arr, 5)<<endl;
 61     cout<<"数组arr的最小公倍数是:"<<GetLCM(arr, 5)<<endl;
 62     
 63     vector<int> v1;
 64     v1.push_back(6);
 65     v1.push_back(9);
 66     v1.push_back(36);
 67     v1.push_back(18);
 68     v1.push_back(72);
 69     cout<<"容器v1的最大公约数是:"<<GetGCD(v1)<<endl;
 70     cout<<"容器v1的最小公倍数是:"<<GetLCM(v1)<<endl;
 71     
 72     cout<<"-1的阶乘是:"<<GetFactorial(-1)<<endl;
 73     cout<<"0的阶乘是:"<<GetFactorial(0)<<endl;
 74     cout<<"1的阶乘是:"<<GetFactorial(1)<<endl;
 75     cout<<"2的阶乘是:"<<GetFactorial(2)<<endl;
 76     cout<<"5的阶乘是:"<<GetFactorial(5)<<endl;
 77     cout<<"13的阶乘是:"<<GetFactorial(13)<<endl;
 78     cout<<"15的阶乘是:"<<GetFactorial(15)<<endl;
 79     cout<<"0-15的阶乘为:"<<endl;
 80     vector<int> fac(10);
 81     FacVecInt(fac, 15);
 82     CoutVecT(fac);
 83     
 84     cout<<"-1234的逆序数是"<<InversionData(-1234)<<endl;
 85     cout<<"-1的逆序数是"<<InversionData(-1)<<endl;
 86     cout<<"0的逆序数是"<<InversionData(0)<<endl;
 87     cout<<"1的逆序数是"<<InversionData(1)<<endl;
 88     cout<<"1234的逆序数是"<<InversionData(1234)<<endl;
 89     cout<<"123456的逆序数是"<<InversionData(123456)<<endl;
 90     
 91     vector<int> v2(10);
 92     int i=17;
 93     cout<<GetPrime(i)<<endl;
 94     cout<<i<<"以内有"<<GetPrime(i, v2)<<"个质数"<<endl;
 95     CoutVecT(v2);
 96     
 97     vector<int> v3(10,9);
 98     vector<int> v4;
 99     vector<int> v5;
100     
101     v5.push_back(2); //2+4+6=12 平均4
102     v5.push_back(4); //方差 (4+0+4)/3
103     v5.push_back(6);  
104     
105     cout<<"v3和:"<<GetSum(v3)<<endl;
106     cout<<"v4和:"<<GetSum(v4)<<endl;
107     cout<<"v5和:"<<GetSum(v5)<<endl;
108     
109     vector<int>::iterator is=v3.begin();
110     vector<int>::iterator ie=v3.end();
111     is++;
112     is++;
113     cout<<"v3后七项和:"<<GetSum<int>(is, ie)<<endl;
114     
115     cout<<"v3平均:"<<GetMean(v3)<<endl;
116     cout<<"v4平均:"<<GetMean(v4)<<endl;
117     cout<<"v5平均:"<<GetMean(v5)<<endl;
118     
119     cout<<"v3方差:"<<GetVariance(v3)<<endl;
120     cout<<"v4方差:"<<GetVariance(v4)<<endl;
121     cout<<"v5方差:"<<GetVariance(v5)<<endl;
122     
123     cout<<"v3标准差:"<<GetStDev(v3)<<endl;
124     cout<<"v4标准差:"<<GetStDev(v4)<<endl;
125     cout<<"v5标准差:"<<GetStDev(v5)<<endl;
126     
127     cout<<"数字分离"<<endl;
128     int i2=256;
129     vector<int> v6(10,1);
130     vector<int> v7(10,2);
131     cout<<DivideDigit(i2)<<endl;
132     cout<<DivideDigit(i2, v6)<<endl;
133     cout<<DivideDigit(i2, v7, false)<<endl;
134     CoutVecT(v6);
135     CoutVecT(v7);
136     
137     cout<<"数字合成"<<endl;
138     vector<int> v8;
139     v8.push_back(15);
140     v8.push_back(16);
141     cout<<JoinDigit(v8,true, true)<<endl;
142     cout<<JoinDigit(v8,true, false)<<endl;
143     cout<<JoinDigit(v8,false, true)<<endl;
144     cout<<JoinDigit(v8,false, false)<<endl;
145     
146     cout<<"数据反序"<<endl;
147     vector<int> v9;
148     v9.push_back(11);
149     v9.push_back(22);
150     v9.push_back(33);
151     InverseVec(v9);
152     CoutVecT(v9);
153 
154     vector<int> v10;
155     v10.push_back(11);
156     v10.push_back(22);
157     v10.push_back(33);
158     vector<int> v11(20);
159     InverseVec(v10, v11);
160     CoutVecT(v10);
161     CoutVecT(v11);
162     
163 
164     cout<<"测试随机数"<<endl;
165     for(int ii=0; ii<5; ii++)
166         cout<<Random(0, 50, true)<<" ";
167     cout<<endl;
168     
169     cout<<"测试数据排序"<<endl;
170     vector<int> v12, v13;
171     RandomVecInt(v12, 10,0, 20);
172     CoutVecT(v12);
173     SortVec(v12, v13, true, true);
174     CoutVecT(v12);
175     CoutVecT(v13);
176     
177     cout<<"等差数列:"<<endl;
178     vector<int> v14;
179     AriVecT(v14, 1, 2, 10);
180     CoutVecT(v14);
181     
182     cout<<"等比数列:"<<endl;
183     vector<int> v15;
184     GeoVecT(v15, 1, 2, 10);
185     CoutVecT(v15);
186     
187     cout<<"测试Fibonacci():"<<endl;
188     cout<<"Fibonacci(-1)="<<Fibonacci(-1)<<endl;
189     cout<<"Fibonacci(-1)="<<Fibonacci(-1)<<endl;
190     for(int fib=1; fib<11; fib++)
191         cout<<Fibonacci(fib)<<" ";
192     cout<<endl;
193     
194     cout<<"测试FibVecInt:"<<endl;
195     vector<int> v16;
196     FibVecInt(v16,10);
197     CoutVecT(v16);
198     
199     return 0;
200 }
201 
202 //仅为方便输出容器的每一项
203 template<typename T>
204 void CoutVecT(const vector<T> &vec)
205 {
206     for(typename vector<T>::size_type si=0; si!=vec.size(); si++)
207         cout<<vec[si]<<" ";
208     cout<<endl;
209 }
210 
211 //编译命令:
212 // g++ MathFunc.cpp test1.cpp -o test1 && test1 -std=c++11(启用C++11特性,在此不需要)
213 // g++ MathFunc.cpp test1.cpp -o test1 && test1
214 
215 //=============
216 //运行结果:
217 //=============
218 // 5是质数
219 // 9不是质数
220 // 5不是完全平方数
221 // 9是完全平方数
222 // 27和18的最大公约数是:9
223 // 27和18的最小公倍数是:54
224 // 数组arr的最大公约数是:3
225 // 数组arr的最小公倍数是:72
226 // 容器v1的最大公约数是:3
227 // 容器v1的最小公倍数是:72
228 // -1的阶乘是:0
229 // 0的阶乘是:1
230 // 1的阶乘是:1
231 // 2的阶乘是:2
232 // 5的阶乘是:120
233 // 13的阶乘是:1932053504
234 // 15的阶乘是:0
235 // 0-15的阶乘为:
236 // 1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 1932053504 
237 // -1234的逆序数是-4321
238 // -1的逆序数是-1
239 // 0的逆序数是0
240 // 1的逆序数是1
241 // 1234的逆序数是4321
242 // 123456的逆序数是654321
243 // 7
244 // 17以内有7个质数
245 // 2 3 5 7 11 13 17 
246 // v3和:90
247 // v4和:0
248 // v5和:12
249 // v3后七项和:72
250 // v3平均:9
251 // v4平均:0
252 // v5平均:4
253 // v3方差:0
254 // v4方差:0
255 // v5方差:2.66667
256 // v3标准差:0
257 // v4标准差:0
258 // v5标准差:1.63299
259 // 数字分离
260 // 3
261 // 3
262 // 3
263 // 2 5 6 
264 // 6 5 2 
265 // 数字合成
266 // 56
267 // 166
268 // 65
269 // 175
270 // 数据反序
271 // 33 22 11 
272 // 11 22 33 
273 // 33 22 11 
274 // 测试随机数
275 // 11 7 47 7 31 
276 // 测试数据排序
277 // 20 9 14 2 13 15 3 10 20 17 
278 // 20 9 14 2 13 15 3 10 20 17 
279 // 2 3 9 10 13 14 15 17 20 
280 // 等差数列:
281 // 1 3 5 7 9 11 13 15 17 19 
282 // 等比数列:
283 // 1 2 4 8 16 32 64 128 256 512 
284 // 测试Fibonacci():
285 // Fibonacci(-1)=0
286 // Fibonacci(-1)=0
287 // 1 1 2 3 5 8 13 21 34 55 
288 // 测试FibVecInt:
289 // 1 1 2 3 5 8 13 21 34 55
290 //=============

 

01 #TYSoft GNU GCC MinGW g++ Makefile
02 #增强的数学函数库的测试
03
04 #=====设置编译器选项=====
05 CXX = g++
06 CCFLAGS =
07 #-ansi -W -Wall
08 #=====设置文件变量=====
09 SOFTNMAE= TYtest
10 OBJECTS = MathFunc.o test1.o
11 LOCFLAGS = ../Include/MathFunc.h
12 #======================
13
14 #=====将.o文件link成.exe文件=====
15 $(SOFTNMAE) : $(OBJECTS)
16     $(CXX) $(CCFLAGS) $(OBJECTS) -o $(SOFTNMAE)
17
18 #=====将.cpp文件编译成.o文件=====
19 MathFunc.o : $(LOCFLAGS)
20 test1.o : $(LOCFLAGS)
21
22 #=====清理文件=====
23 .PHONY : clean
24 clean :
25     -rm $(SOFTNMAE) $(OBJECTS)
posted @ 2012-06-01 21:08  天远  阅读(343)  评论(0)    收藏  举报

版权所有 © 2010-2020 YuanPeirong TianYuan All Rights Reserved. Powered By 天远