增强的数学函数库(第1次发布,功能不断增加中)
2012-06-01 21:04
393 查看
/*- ========================================================== * 文件名 :MathFunc.h * 开发人员:袁培荣 * 当前版本:1.3.3.2595 (第1次发布,功能不断增加中) * 创建时间:2012-05-28 * 修改时间:2012-05-30 * 功能说明:增强的数学函数库的声明 * 版权说明:版权所有 袁培荣 YuanPeirong * 编译环境:Windows 7(x64) SP1 简体中文专业版 * 编译器: Visual Studio 2010 SP1(中文旗舰版) MinGW 20120426 GNU GCC 4.6.2 Visual C++ 6.0 SP6(中文企业版) - ==========================================================*/ //编译测试情况: // 1.Visual Studio 2010 SP1(中文旗舰版): // 在Release和Debug下都编译通过,测试运行正常。 // 2.MinGW 20120426 GNU GCC 4.6.2: // 编译通过,测试运行正常。 // 3.Visual C++ 6.0 SP6(中文企业版) // 未测试。 #ifndef MathFunc_H_TYCppStdLib //防止头文件重复包含 #define MathFunc_H_TYCppStdLib #ifdef MathFunc_DLL_API //为导出DLL预留 #else #define MathFunc_DLL_API _declspec(dllimport) #endif #include <cstdlib> #include <cmath> #include <ctime> #include <vector> //vector容器 #include <algorithm> //泛型算法 #include <numeric> //泛化算法 //#include <functional> //标准库的函数对象类型在此定义 using namespace std; namespace TYCppStdLib //所有功能都封装在命名空间TYCppStdLib中 { //产生一个随机整数 int Random( int minValue=-32768, //设置数据的最大值(包含) int maxValue=32767, //设置数据的最大值(包含) bool isPrime=false //是否必须要返回质数 ); //产生随机纯小数 double Random( double minValue=0, //设置数据的最小值(包含) double maxValue=1, //设置数据的最大值(包含) bool get0and1=false //指明是否可以产生0和1 ); //产生一组随机整数(此函数是以前写的,将要被我弃用,因为使用了不安全的数组) //建议使用功能更加强大的 RandomVecInt函数(在下文中定义) bool Random( int *data, //用于存放产生的整数的数组首地址 int num, //设置要产生的数据个数 int minValue=-32768, //设置数据的最小值(包含) int maxValue=32767, //设置数据的最大值(包含) bool different=false //设置数据是否要互不相同 ); //为Random函数定义相应的类,方便生成函数对象作为泛型算法的发生器 class Random_cls { private: int minValue; int maxValue; bool isPrime; public: Random_cls(int min, int max, bool isp); int operator()(); }; bool IsPrime(int n); //判断质数 //获取n以内(含n)的所有质数的个数 int GetPrime(int n); //获取n以内(含n)的所有质数,并返回质数的个数 int GetPrime(int n, vector<int> &vec); //int GetPrime(int n, int *p); //数组版本,因不安全,不想支持 bool IsSquare(int n); //判断完全平方数 //求两个数的最大公约数 int GetGCD(int m, int n); //求一组数据的最大公约数(不安全,不推荐使用) int GetGCD(const int *p, int count); //或者是int GetGCD(const int p[], int count); //求一组数据的最大公约数(安全,推荐使用) int GetGCD(vector<int> &vec); //求两个数的最小公倍数 int GetLCM(int m, int n); //求一组数据的最小公倍数(不安全,不推荐使用) int GetLCM(const int *p, int count); //或者是int GetLCM(const int p[], int count); //求一组数据的最小公倍数(安全,推荐使用) int GetLCM(vector<int> &vec); int GetFactorial(int n); //求阶乘(13以内)(非递归和递归方式实现) //获得0到n的阶乘结果(n超过13时设为13) //这里不用到GetFactorial,因为效率太低 void FacVecInt(vector<int> &vec, int n); int InversionData(int n); //求整数的逆序数,如6589返回9856 //以下用到 vector 的函数都可以写相应的数组版本 //但是因为数组是不安全的东西,不想再支持数组 //获取数字的位数 int DivideDigit(int n); //获取数字的各个位上的数值,并返回分离出的数字个数 int DivideDigit( int n, //待求数字 vector<int> &vec, //存储结果 bool forward=true //ture:高位在前存储,false:低位在前存储 ); //获取数字的各个位上的数值(高位在前),并返回分离出的数字个数 //int DivideDigitA(int n, vector<int> &vec); //不再需要 //获取数字的各个位上的数值(低位在前),并返回分离出的数字个数 //int DivideDigitB(int n, vector<int> &vec); //不再需要 //将一组数据按位合成一个数 int JoinDigit( const vector<int> &vec, //一组数据 bool forward=true, //ture:高位在前,false:低位在前 bool onlyBit=false //数据中的每一位是否只取其个位 ); //生成一组随机数据(用随机数据初始化vector<int>) void RandomVecInt( vector<int> &vec, //存放数据的容器 int num, //产生数据的个数 int minValue=-32768, //设置数据的最大值(包含) int maxValue=32767, //设置数据的最大值(包含) bool isPrime=false //产生的数据是否必须为质数 ); //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(非递归和递归方式实现) int Fibonacci(int n); //求Fibonacci数列的前N项(用Fibonacci数列初始化vector<int>) //这里不用到Fibonacci函数,因为效率太低 void FibVecInt(vector<int> &vec, int num); //求一组数据的和 template<typename T> T GetSum(const vector<T> &vec); // template<typename T> //初始实现版本 // T GetSum(typename vector<T>::const_iterator start, typename vector<T>::const_iterator end); //调用方式:T sum=GetSum(s, e)或者 GetSum<T>(s, e) template<typename T, typename InputIterator> //更加泛化的实现版本 T GetSum(InputIterator start, InputIterator end); //调用方式:T sum=GetSum(s, e)或者 GetSum<T>(s, e) //求一组数据的算术平均数(涉及到除法,因此返回值转为double,下同) template<typename T> double GetMean(const vector<T> &vec); //求一组数据的方差 template<typename T> double GetVariance(const vector<T> &vec); //求一组数据的标准差 template<typename T> double GetStDev(const vector<T> &vec); //将一组数据反序,并覆盖原数据 template<typename T> void InverseVec(vector<T> &vec); //结果覆盖原数据 //将一组数据反序,不覆盖原数据 template<typename T> void InverseVec( const vector<T> &vec1, //原数据 vector<T> &vec2 //逆序数据 ); //比较两个数的大小 template<typename T> bool IsBig(const T &m, const T &n); template<typename T> bool IsSmall(const T &m, 4000 const T &n); //将一组数据进行排序,并覆盖原数据 template<typename T> void SortVec( vector<T> &vec, //结果覆盖原数据 bool smallToBig=true, //ture:从小到大,false:从大到小 bool eraseUnique=false //ture:去除重复值,false:不去除重复值 ); //将一组数据进行排序,不覆盖原数据 template<typename T> void SortVec( const vector<T> &vec1, //原数据 vector<T> &vec2, //逆序数据 bool smallToBig=true, //ture:从小到大,false:从大到小 bool eraseUnique=false //ture:去除重复值,false:不去除重复值 ); //生成等差数列(Arithmetic Sequence)(用等差数列初始化vector<T>) template<typename T> void AriVecT( vector<T> &vec, //存储数据 T fisrt, //首项 T tolerance, //公差 T num //项数 ); //生成等比数列(Geometric Sequence)(用等比数列初始化vector<T>) template<typename T> void GeoVecT( vector<T> &vec, //存储数据 T fisrt, //首项 T comRatio, //公比 T num //项数 ); // 仅为测试 // template<typename T> // T GetTest(T n); } //为了兼容各编译器,特别是VC++6.0这种低级的旧版本编译器 //只好采用模板的包含编译模式 //模板的实现放在.hpp文件中,编译时不单独编译 //而事实上, Visual Studio 2010也不能采用更先进的分离编译模式 //而对C++标准支持得最好的MinGW也不能支持更先进的分离编译模式 //除了国外极少数的冷门商业编译器支持分离编译模式 //我现有的编译器都不只支持,因此只能头文件反向包含源文件的做法 //采用了boost的做法,将其反缀名定为 .hpp ,即 .h + .cpp #include "MathFunc.hpp" //在编译时,应将此hpp文件当做头文件而非源文件,即不单独编译 #endif //摘自:SGI STL /* template<typename _InputIterator, typename _Tp> inline _Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) __glibcxx_requires_valid_range(__first, __last); for (; __first != __last; ++__first) __init = __init + *__first; return __init; } */
/*- ========================================================== * 文件名 :MathFunc.cpp * 开发人员:袁培荣 * 当前版本:1.3.3.2595 (第1次发布,功能不断增加中) * 创建时间:2012-05-28 * 修改时间:2012-05-30 * 功能说明:增强的数学函数库的实现 * 版权说明:版权所有 袁培荣 YuanPeirong * 编译环境:Windows 7(x64) SP1 简体中文专业版 * 编译器: Visual Studio 2010 SP1(中文旗舰版) MinGW 20120426 GNU GCC 4.6.2 Visual C++ 6.0 SP6(中文企业版) - ==========================================================*/ //编译测试情况: // 1.Visual Studio 2010 SP1(中文旗舰版): // 在Release和Debug下都编译通过,测试运行正常。 // 2.MinGW 20120426 GNU GCC 4.6.2: // 编译通过,测试运行正常。 // 3.Visual C++ 6.0 SP6(中文企业版) // 未测试。 #ifndef MathFunc_DLL_ForAPI #define MathFunc_DLL_ForAPI #define MathFunc_DLL_API _declspec(dllexport) //为导出DLL预留 #endif #include "../Include/MathFunc.h" using namespace std; using namespace TYCppStdLib; //产生一个随机整数 int TYCppStdLib::Random( int minValue, //设置数据的最大值(包含) int maxValue, //设置数据的最大值(包含) bool isPrime //是否必须要返回质数 ) { if(maxValue<minValue) return 0;//return false; if(minValue<-32768) minValue=-32768; if(maxValue>32767) maxValue=32767; int ix; static bool randomFisrt=true; if(randomFisrt) srand(time(static_cast<time_t>(0))); randomFisrt=false; ix=rand(); ix=ix%(maxValue-minValue+1)+minValue; if(!isPrime) return ix; bool isp=IsPrime(ix); if(isp) return ix; while(!isp) { ix=rand(); ix=ix%(maxValue-minValue+1)+minValue; isp=IsPrime(ix); } return ix; } //产生随机纯小数 double TYCppStdLib::Random(double minValue, double maxValue, bool get0and1) { if(maxValue<minValue) return 0;//return false; if(minValue<0) minValue=0; if(maxValue>1) maxValue=1; double dx; int ix1, ix2; ix1=(int)(minValue*32767); ix2=(int)(maxValue*32767); ix1=Random(ix1, ix2); if(false==get0and1 && 0==minValue && 1==maxValue) { if(!ix1) ix1=1; if(ix1==32767) ix1=32766; } dx=(double)(ix1)/32767; return dx; } //产生一组随机整数(此函数是以前写的,将要被我弃用,因为使用了不安全的数组) bool TYCppStdLib::Random(int *data, int num, int minValue, int maxValue, bool different) { if(num<1 || maxValue<minValue) return false; if(minValue<-32768) minValue=-32768; if(maxValue>32767) maxValue=32767; if(different && (maxValue-minValue+1)<num) return false; int ii, ij, ix; for(ii=0;ii<num;ii++) { while(1) { ix=Random(minValue, maxValue); if(!different) break; for(ij=0;ij<ii;ij++) { if(ix==*(data+ij)) break; } if(ij==ii) break; } *(data+ii)=ix; } return true; } //以下的函数是正确的,只是将数组形参写成指针形式更好,因此弃用 // 产生一批随机整数 // bool Random( // int data[], //用于存放产生的整数的数组 // int num, //设置要产生的数据个数 // int minValue=-32768, //设置数据的最小值(包含) // int maxValue=32767,//设置数据的最大值(包含) // bool different=false //设置数据是否要互不相同 // ); // bool Random(int data[], int num, int minValue, int maxValue, bool different) // { // if(num<1 || maxValue<minValue) // return false; // if(minValue<-32768) // minValue=-32768; // if(maxValue>32767) // maxValue=32767; // if(different && (maxValue-minValue+1)<num) // return false; // int ii, ij=0, ix; // for(ii=0;ii<num;ii++) // { // while(1) // { // ix=Random(minValue, maxValue); // if(!different) // break; // for(ij=0;ij<ii;ij++) // { // if(ix==data[ij]) // break; // } // if(ij==ii) // break; // } // data[ii]=ix; // } // return true; // } //为Random函数定义相应的类,方便生成函数对象作为泛型算法的发生器 TYCppStdLib::Random_cls::Random_cls(int min, int max, bool isp) { minValue=min; maxValue=max; isPrime=isp; } int TYCppStdLib::Random_cls::operator()() { return Random(minValue, maxValue, isPrime); } //判断质数 bool TYCppStdLib::IsPrime(int n) { n=abs(n); //允许n是负数 if(n<2) return false; int m=static_cast<int>(sqrt(static_cast<double>(n)))+1; for(int i=2; i<m+1; i++) //i<m或i<m+1 if(n%i==0) return false; return true; } //获取n以内(含n)的所有质数的个数 int TYCppStdLib::GetPrime(int n) { if(n<2) return 0; if(2==n) return 1; int num=1; for(int i=3; i<=n; i=i+2) if(IsPrime(i)) num++; return num; } //获取n以内(含n)的所有质数,并返回质数的个数 int TYCppStdLib::GetPrime(int n, vector<int> &vec) { vec.clear(); if(n<2) return 0; if(2==n) { vec.push_back(2); return 1; } vec.push_back(2); for(int i=3; i<=n; i=i+2) if(IsPrime(i)) vec.push_back(i); return static_cast<int>(vec.size()); } //判断完全平方数 bool TYCppStdLib::IsSquare(int n) { if(n<0) return false; int m=static_cast<int>(sqrt(static_cast<double>(n))); if(m*m==n) return true; return false; } //求两个数的最大公约数 int TYCppStdLib::GetGCD(int m, int n) { if(!m && !n) return 0; if(!m) return n; if(!n) return m; int r; while(r=m%n) { m=n; n=r; } return abs(n); } //求一组数据的最大公约数(不安全,不推荐使用) int TYCppStdLib::GetGCD(const int *p, int count) { if(!p || count<2) return 0; int gcd=p[0]; for(int i=1; i!=count; i++) gcd=GetGCD(gcd,p[i]); return abs(gcd); } //求一组数据的最大公约数(安全,推荐使用) int TYCppStdLib::GetGCD(vector<int> &vec) { int vsize=vec.size(); if(vsize<2) return 0; int gcd=vec[0]; for(int i=1; i!=vsize; i++) gcd=GetGCD(gcd, vec[i]); return abs(gcd); } //求两个数的最小公倍数 int TYCppStdLib::GetLCM(int m, int n) { if(!m || !n) return 0; int lcm=m*n/GetGCD(m, n); //GetGCD(m, n)不会再返回0 return abs(lcm); //因为返回0的情况在前面已经排除 } //求一组数据的最小公倍数(不安全,不推荐使用) int TYCppStdLib::GetLCM(const int *p, int count) { if(!p || count<2) return 0; int lcm=p[0]; for(int i=1; i!=count; i++) lcm=GetLCM(lcm, p[i]); return abs(lcm); } //求一组数据的最小公倍数(安全,推荐使用) int TYCppStdLib::GetLCM(vector<int> &vec) { int vsize=vec.size(); if(vsize<2) return 0; int lcm=vec[0]; for(int i=1; i!=vsize; i++) lcm=GetLCM(lcm, vec[i]); return abs(lcm); } //求阶乘(13以内)(非递归) int TYCppStdLib::GetFactorial(int n) { if(n<0 || n>13) return 0; if(n<2) return 1; int fac=1; for(int i=2; i<=n; i++) fac=fac*i; return fac; } //以下为求阶乘的递归实现,两种方法效率几乎相同 //但为减小函数重复调用开销,选择非递归方式 //求阶乘(13以内)(递归) // int TYCppStdLib::GetFactorial(int n) // { // if(n<0 || n>13) // return 0; // if(n<2) // return 1; // return GetFactorial(n-1)*n; // } //获得0到n的阶乘结果(n超过13时设为13) //这里不用到GetFactorial,因为效率太低 void TYCppStdLib::FacVecInt(vector<int> &vec, int n) { vec.clear(); if(n<0) return; vec.push_back(1); if(0==n) return; vec.push_back(1); if(1==n) return; if(n>13) n=13; int fac=1; for(int i=1; i!=n; i++) { fac=fac*(i+1); vec.push_back(fac); } } //求整数的逆序数,如6589返回9856 int TYCppStdLib::InversionData(int n) { int s=0; while(n) { s=10*s+n%10; n=n/10; } return s; } //获取数字的位数 int TYCppStdLib::DivideDigit(int n) { n=abs(n); if(0==n) return 1; int num=0; while(n) { n=n/10; num++; } return num; } //获取数字的各个位上的数值,并返回分离出的数字个数 int TYCppStdLib::DivideDigit( int n, //待求数字 vector<int> &vec, //存储结果 bool forward //ture:高位在前存储,false:低位在前存储 ) { n=abs(n); vec.clear(); int num=0; if(0==n) { vec.push_back(0); return 1; } if(forward) { while(n) { vec.insert(vec.begin(), n%10); n=n/10; num++; } } else { while(n) { vec.push_back(n%10); n=n/10; num++; } } return num; } //以下两个函数的功能已经被集成到上面的函数中 //获取数字的各个位上的数值(高位在前),并返回分离出的数字个数 // int TYCppStdLib::DivideDigitA(int n, vector<int> &vec) // { // n=abs(n); // vec.clear(); // if(0==n) // { // vec.push_back(0); // return 1; // } // int num=0; // while(n) // { // vec.insert(vec.begin(), n%10); // n=n/10; // num++; // } // return num; // } //获取数字的各个位上的数值(低位在前),并返回分离出的数字个数 // int TYCppStdLib::DivideDigitB(int n, vector<int> &vec) // { // n=abs(n); // vec.clear(); // if(0==n) // { // vec.push_back(0); // return 1; // } // int num=0; // while(n) // { // vec.push_back(n%10); // n=n/10; // num++; // } // return num; // } //将一组数据按位合成一个数 int TYCppStdLib::JoinDigit( const vector<int> &vec, //一组数据 bool forward, //ture:高位在前,false:低位在前 bool onlyBit //数据中的每一位是否只取其个位 ) { if(vec.empty()) return 0; int sum=0; vector<int>::size_type si; if(forward) { for(si=0; si!=vec.size(); si++) { if(onlyBit) sum=sum*10+(vec[si]%10); else sum=sum*10+vec[si]; } } else { for(si=vec.size()-1; si!=-1; si--) { if(onlyBit) sum=sum*10+(vec[si]%10); else sum=sum*10+vec[si]; } } return sum; } //生成一组随机数据(用随机数据初始化vector<int>) void TYCppStdLib::RandomVecInt( vector<int> &vec, //存放数据的容器 int num, //产生数据的个数 int minValue, //设置数据的最大值(包含) int maxValue, //设置数据的最大值(包含) bool isPrime //产生的数据是否必须为质数 ) { vec.clear(); if (num<1) return; vec.resize(num); generate(vec.begin(), vec.end(), Random_cls(minValue, maxValue, isPrime)); return; } //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(非递归) int TYCppStdLib::Fibonacci(int n) { if(n<1) return 0; if(1==n || 2==n) return 1; int fib; int n_1=1; int n_2=1; for(int i=2; i!=n; i++) { fib=n_1+n_2; n_2=n_1; n_1=fib; } return fib; } //以下为求Fibonacci数列的第N项的递归实现,两种方法效率几乎相同 //但为减小函数重复调用开销,选择非递归方式 //求Fibonacci数列的第N项 F1=1 F2=1 F3=2 ……(递归) // int TYCppStdLib::Fibonacci(int n) // { // if(n<1) // return 0; // if(1==n || 2==n) // return 1; // return (Fibonacci(n-1)+Fibonacci(n-2)); // } //求Fibonacci数列的前N项(用Fibonacci数列初始化vector<int>) //这里不用到Fibonacci函数,因为效率太低 void TYCppStdLib::FibVecInt(vector<int> &vec, int num) { vec.clear(); if(num<1) return; vec.push_back(1); if(1==num) return; vec.push_back(1); if(2==num) return; int n; int n_1=1; int n_2=1; for(int i=2; i!=num; i++) { n=n_1+n_2; vec.push_back(n); n_2=n_1; n_1=n; } } // 仅为测试 // template<typename T> // T TYCppStdLib::GetTest(T n) // { // return (-n); // }
/*- ========================================================== * 文件名 :MathFunc.hpp * 开发人员:袁培荣 * 当前版本:1.3.3.2595 (第1次发布,功能不断增加中) * 创建时间:2012-05-28 * d86b 修改时间:2012-05-30 * 功能说明:增强的数学函数库的模板实现 * 版权说明:版权所有 袁培荣 YuanPeirong * 编译环境:Windows 7(x64) SP1 简体中文专业版 * 编译器: Visual Studio 2010 SP1(中文旗舰版) MinGW 20120426 GNU GCC 4.6.2 Visual C++ 6.0 SP6(中文企业版) - ==========================================================*/ //编译测试情况: // 1.Visual Studio 2010 SP1(中文旗舰版): // 在Release和Debug下都编译通过,测试运行正常。 // 2.MinGW 20120426 GNU GCC 4.6.2: // 编译通过,测试运行正常。 // 3.Visual C++ 6.0 SP6(中文企业版) // 未测试。 #ifndef MathFunc_HPP_TYCppStdLib //防止头文件重复包含 #define MathFunc_HPP_TYCppStdLib #include <iostream> //求一组数据的和 //export template<typename T> template<typename T> T TYCppStdLib::GetSum(const vector<T> &vec) { T sum=accumulate(vec.begin(), vec.end(), static_cast<T>(0)); return sum; } //初始实现版本 // template<typename T> // T TYCppStdLib::GetSum( // typename vector<T>::const_iterator start // , typename vector<T>::const_iterator end // ) // { // T sum=accumulate(start, end, static_cast<T>(0)); // return sum; // } //更加泛化的实现版本 template<typename T, typename InputIterator> T TYCppStdLib::GetSum(InputIterator start, InputIterator end) { T sum=accumulate(start, end, static_cast<T>(0)); return sum; } //求一组数据的算术平均数(涉及到除法,因此返回值转为double,下同) template<typename T> double TYCppStdLib::GetMean(const vector<T> &vec) { int num=static_cast<int>(vec.size()); if(0==num) return static_cast<double>(0); T sum=accumulate(vec.begin(), vec.end(), static_cast<T>(0)); return (static_cast<double>(sum))/(static_cast<double>(num)); } //求一组数据的方差(第1正确实现版本) // template<typename T> // double TYCppStdLib::GetVariance(const vector<T> &vec) // { // double mean=GetMean(vec); // vector<double> temp; // for(vector<double>::size_type si=0; si!=vec.size(); si++) // { // vec为空也不会出错 // double vsi=static_cast<double>(vec[si]); // temp.push_back((vsi-mean)*(vsi-mean)); // } // return GetMean(temp); // } //求一组数据的方差(优化实现版本) //=== //优化原因: // 1.避免构造临时vector, // 2.避免调用外部函数对临时vector的遍历 // 3.减少外部函数的调用次数 // 4.更快的处理空数据 // 5.减少内存占用 //=== template<typename T> double TYCppStdLib::GetVariance(const vector<T> &vec) { int num=static_cast<int>(vec.size()); if(0==num) return static_cast<double>(0); double mean=GetMean(vec); double sum=0; //sum和平均数有关,而平均数已经是double了 for(vector<double>::size_type si=0; si!=vec.size(); si++) { double vsi=static_cast<double>(vec[si]); sum=sum+((vsi-mean)*(vsi-mean)); } return sum/(static_cast<double>(num)); } //求一组数据的标准差 template<typename T> double TYCppStdLib::GetStDev(const vector<T> &vec) { return sqrt(GetVariance(vec)); } //将一组数据反序,并覆盖原数据 template<typename T> void TYCppStdLib::InverseVec(vector<T> &vec) //结果覆盖原数据 { vector<T> vec2; for(typename vector<T>::size_type si=0; si!=vec.size(); si++) vec2.insert(vec2.begin(), vec[si]); vec=vec2; return; } //将一组数据反序,不覆盖原数据 template<typename T> void TYCppStdLib::InverseVec( const vector<T> &vec1, //原数据 vector<T> &vec2 //逆序数据 ) { vec2.clear(); for(typename vector<T>::size_type si=0; si!=vec1.size(); si++) vec2.insert(vec2.begin(), vec1[si]); return; } //比较两个数的大小 template<typename T> bool TYCppStdLib::IsBig(const T &m, const T &n) { return m>=n; } template<typename T> bool TYCppStdLib::IsSmall(const T &m, const T &n) { return m<n; } //将一组数据进行排序,并覆盖原数据 template<typename T> void TYCppStdLib::SortVec( vector<T> &vec, //结果覆盖原数据 bool smallToBig, //ture:从小到大,false:从大到小 bool eraseUnique //ture:去除重复值,false:不去除重复值 ) { if(smallToBig) sort(vec.begin(), vec.end(), IsSmall<T>); //标准库有less和less_equal //也可以写成sort(vec.begin(), vec.end()); //但在MinGW和VS2010的Release下编译通过,运行正常 //VS2010的Debug下编译通过,运行错误 //但写成sort(vec.begin(), vec.end(), IsSmall<T>); //在MinGW和VS2010的Release,Debug下都编译通过而运行正常 else sort(vec.begin(), vec.end(), IsBig<T>); //标准库有greater和greater_equal if(eraseUnique) { typename vector<T>::iterator end_unique= unique(vec.begin(), vec.end()); vec.erase(end_unique, vec.end()); } } //将一组数据进行排序,不覆盖原数据 template<typename T> void TYCppStdLib::SortVec( const vector<T> &vec1, //原数据 vector<T> &vec2, //逆序数据 bool smallToBig, //ture:从小到大,false:从大到小 bool eraseUnique //ture:去除重复值,false:不去除重复值 ) { vec2=vec1; SortVec(vec2, smallToBig, eraseUnique); } //生成等差数列(Arithmetic Sequence)(用等差数列初始化vector<T>) template<typename T> void TYCppStdLib::AriVecT( vector<T> &vec, //存储数据 T fisrt, //首项 T tolerance, //公差 T num //项数 ) { vec.clear(); if(num<1) return; for(int i=0; i!=num; i++) { vec.push_back(fisrt); fisrt=fisrt+tolerance; } } //生成等比数列(Geometric Sequence)(用等比数列初始化vector<T>) template<typename T> void TYCppStdLib::GeoVecT( vector<T> &vec, //存储数据 T fisrt, //首项 T comRatio, //公比 T num //项数 ) { vec.clear(); if(num<1) return; for(int i=0; i!=num; i++) { vec.push_back(fisrt); fisrt=fisrt*comRatio; } } #endif
/*- ========================================================== * 文件名 :test1.cpp * 开发人员:袁培荣 * 当前版本:1.3.3.2595 (第1次发布,功能不断增加中) * 创建时间:2012-05-28 * 修改时间:2012-05-30 * 功能说明:增强的数学函数库的测试代码 * 版权说明:版权所有 袁培荣 YuanPeirong * 编译环境:Windows 7(x64) SP1 简体中文专业版 * 编译器: Visual Studio 2010 SP1(中文旗舰版) MinGW 20120426 GNU GCC 4.6.2 Visual C++ 6.0 SP6(中文企业版) - ==========================================================*/ //编译测试情况: // 1.Visual Studio 2010 SP1(中文旗舰版): // 在Release和Debug下都编译通过,测试运行正常。 // 2.MinGW 20120426 GNU GCC 4.6.2: // 编译通过,测试运行正常。 // 3.Visual C++ 6.0 SP6(中文企业版) // 未测试。 #include <iostream> #include "../Include/MathFunc.h" //#include <vector> //MathFunc.h中已经包含此头文件 using namespace std; using namespace TYCppStdLib; template<typename T> //仅为方便输出容器的每一项 void CoutVecT(const vector<T> &vec); int main(int argc, char* argv[]) { if(IsPrime(5)) cout<<"5是质数"<<endl; else cout<<"5不是质数"<<endl; if(IsPrime(9)) cout<<"9是质数"<<endl; else cout<<"9不是质数"<<endl; if(IsSquare(5)) cout<<"5是完全平方数"<<endl; else cout<<"5不是完全平方数"<<endl; if(IsSquare(9)) cout<<"9是完全平方数"<<endl; else cout<<"9不是完全平方数"<<endl; cout<<"27和18的最大公约数是:"<<GetGCD(27, 18)<<endl; cout<<"27和18的最小公倍数是:"<<GetLCM(27, 18)<<endl; int arr[5]={6,9,36,18,72}; cout<<"数组arr的最大公约数是:"<<GetGCD(arr, 5)<<endl; cout<<"数组arr的最小公倍数是:"<<GetLCM(arr, 5)<<endl; vector<int> v1; v1.push_back(6); v1.push_back(9); v1.push_back(36); v1.push_back(18); v1.push_back(72); cout<<"容器v1的最大公约数是:"<<GetGCD(v1)<<endl; cout<<"容器v1的最小公倍数是:"<<GetLCM(v1)<<endl; cout<<"-1的阶乘是:"<<GetFactorial(-1)<<endl; cout<<"0的阶乘是:"<<GetFactorial(0)<<endl; cout<<"1的阶乘是:"<<GetFactorial(1)<<endl; cout<<"2的阶乘是:"<<GetFactorial(2)<<endl; cout<<"5的阶乘是:"<<GetFactorial(5)<<endl; cout<<"13的阶乘是:"<<GetFactorial(13)<<endl; cout<<"15的阶乘是:"<<GetFactorial(15)<<endl; cout<<"0-15的阶乘为:"<<endl; vector<int> fac(10); FacVecInt(fac, 15); CoutVecT(fac); cout<<"-1234的逆序数是"<<InversionData(-1234)<<endl; cout<<"-1的逆序数是"<<InversionData(-1)<<endl; cout<<"0的逆序数是"<<InversionData(0)<<endl; cout<<"1的逆序数是"<<InversionData(1)<<endl; cout<<"1234的逆序数是"<<InversionData(1234)<<endl; cout<<"123456的逆序数是"<<InversionData(123456)<<endl; vector<int> v2(10); int i=17; cout<<GetPrime(i)<<endl; cout<<i<<"以内有"<<GetPrime(i, v2)<<"个质数"<<endl; CoutVecT(v2); vector<int> v3(10,9); vector<int> v4; vector<int> v5; v5.push_back(2); //2+4+6=12 平均4 v5.push_back(4); //方差 (4+0+4)/3 v5.push_back(6); cout<<"v3和:"<<GetSum(v3)<<endl; cout<<"v4和:"<<GetSum(v4)<<endl; cout<<"v5和:"<<GetSum(v5)<<endl; vector<int>::iterator is=v3.begin(); vector<int>::iterator ie=v3.end(); is++; is++; cout<<"v3后七项和:"<<GetSum<int>(is, ie)<<endl; cout<<"v3平均:"<<GetMean(v3)<<endl; cout<<"v4平均:"<<GetMean(v4)<<endl; cout<<"v5平均:"<<GetMean(v5)<<endl; cout<<"v3方差:"<<GetVariance(v3)<<endl; cout<<"v4方差:"<<GetVariance(v4)<<endl; cout<<"v5方差:"<<GetVariance(v5)<<endl; cout<<"v3标准差:"<<GetStDev(v3)<<endl; cout<<"v4标准差:"<<GetStDev(v4)<<endl; cout<<"v5标准差:"<<GetStDev(v5)<<endl; cout<<"数字分离"<<endl; int i2=256; vector<int> v6(10,1); vector<int> v7(10,2); cout<<DivideDigit(i2)<<endl; cout<<DivideDigit(i2, v6)<<endl; cout<<DivideDigit(i2, v7, false)<<endl; CoutVecT(v6); CoutVecT(v7); cout<<"数字合成"<<endl; vector<int> v8; v8.push_back(15); v8.push_back(16); cout<<JoinDigit(v8,true, true)<<endl; cout<<JoinDigit(v8,true, false)<<endl; cout<<JoinDigit(v8,false, true)<<endl; cout<<JoinDigit(v8,false, false)<<endl; cout<<"数据反序"<<endl; vector<int> v9; v9.push_back(11); v9.push_back(22); v9.push_back(33); InverseVec(v9); CoutVecT(v9); vector<int> v10; v10.push_back(11); v10.push_back(22); v10.push_back(33); vector<int> v11(20); InverseVec(v10, v11); CoutVecT(v10); CoutVecT(v11); cout<<"测试随机数"<<endl; for(int ii=0; ii<5; ii++) cout<<Random(0, 50, true)<<" "; cout<<endl; cout<<"测试数据排序"<<endl; vector<int> v12, v13; RandomVecInt(v12, 10,0, 20); CoutVecT(v12); SortVec(v12, v13, true, true); CoutVecT(v12); CoutVecT(v13); cout<<"等差数列:"<<endl; vector<int> v14; AriVecT(v14, 1, 2, 10); CoutVecT(v14); cout<<"等比数列:"<<endl; vector<int> v15; GeoVecT(v15, 1, 2, 10); CoutVecT(v15); cout<<"测试Fibonacci():"<<endl; cout<<"Fibonacci(-1)="<<Fibonacci(-1)<<endl; cout<<"Fibonacci(-1)="<<Fibonacci(-1)<<endl; for(int fib=1; fib<11; fib++) cout<<Fibonacci(fib)<<" "; cout<<endl; cout<<"测试FibVecInt:"<<endl; vector<int> v16; FibVecInt(v16,10); CoutVecT(v16); return 0; } //仅为方便输出容器的每一项 template<typename T> void CoutVecT(const vector<T> &vec) { for(typename vector<T>::size_type si=0; si!=vec.size(); si++) cout<<vec[si]<<" "; cout<<endl; } //编译命令: // g++ MathFunc.cpp test1.cpp -o test1 && test1 -std=c++11(启用C++11特性,在此不需要) // g++ MathFunc.cpp test1.cpp -o test1 && test1 //============= //运行结果: //============= // 5是质数 // 9不是质数 // 5不是完全平方数 // 9是完全平方数 // 27和18的最大公约数是:9 // 27和18的最小公倍数是:54 // 数组arr的最大公约数是:3 // 数组arr的最小公倍数是:72 // 容器v1的最大公约数是:3 // 容器v1的最小公倍数是:72 // -1的阶乘是:0 // 0的阶乘是:1 // 1的阶乘是:1 // 2的阶乘是:2 // 5的阶乘是:120 // 13的阶乘是:1932053504 // 15的阶乘是:0 // 0-15的阶乘为: // 1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 1932053504 // -1234的逆序数是-4321 // -1的逆序数是-1 // 0的逆序数是0 // 1的逆序数是1 // 1234的逆序数是4321 // 123456的逆序数是654321 // 7 // 17以内有7个质数 // 2 3 5 7 11 13 17 // v3和:90 // v4和:0 // v5和:12 // v3后七项和:72 // v3平均:9 // v4平均:0 // v5平均:4 // v3方差:0 // v4方差:0 // v5方差:2.66667 // v3标准差:0 // v4标准差:0 // v5标准差:1.63299 // 数字分离 // 3 // 3 // 3 // 2 5 6 // 6 5 2 // 数字合成 // 56 // 166 // 65 // 175 // 数据反序 // 33 22 11 // 11 22 33 // 33 22 11 // 测试随机数 // 11 7 47 7 31 // 测试数据排序 // 20 9 14 2 13 15 3 10 20 17 // 20 9 14 2 13 15 3 10 20 17 // 2 3 9 10 13 14 15 17 20 // 等差数列: // 1 3 5 7 9 11 13 15 17 19 // 等比数列: // 1 2 4 8 16 32 64 128 256 512 // 测试Fibonacci(): // Fibonacci(-1)=0 // Fibonacci(-1)=0 // 1 1 2 3 5 8 13 21 34 55 // 测试FibVecInt: // 1 1 2 3 5 8 13 21 34 55 //=============
相关文章推荐
- 增强的数学函数库(第1次发布,功能不断增加中)
- 增强的数学函数库(第1次发布,功能不断增加中)
- druid发布0.2.1版,增加sql统计的merge功能。
- .NET图像处理库ImageGear for .NET v23.2发布,增加新的PDF压缩功能
- Atom 1.23发布:功能增强,兼容性更好
- 条形码组件VintaSoftBarcode.NET SDK v10.0发布,增强条码识别、生成功能
- Cordova webapp实战开发:(7)如何通过简单的方法做到,不重新发布APP来修复bug、增加功能、或者躲开苹果的一些严格审核?
- WayOs帐号获取保存工具增加提交的功能,WayOs扩展WAN口工具1.6发布增加网卡和VLAN混合组网功能
- 自已动手写的轮播图插件,功能不断增加中,可以下载
- PDF 补丁丁 0.6.0.3413 版发布(修复提取图片问题,增加自动检查软件更新功能)
- Oracle11g新特性:在线操作功能增强-表增加包含默认值的字段(转载)
- XFdtd 7.3.2发布增强生物电磁学中的核磁共振功能
- BCM平台全自动刷机软件,TFTP正式版1.62隆重发布,增加固件记忆功能
- 将泡泡淘客软件和wordpress整合,为其增加文章发布功能
- 陌陌发布新版 增加阅后即焚和短视频功能
- ADO助手V1.20发布了---增加根据SQL生成MFC数据库类的功能
- 墨子题库系统全新2.0版正式发布-增加在线考试功能
- 跨平台远程框架Remoting SDK发布v9新版本,增加新的Code First服务器等功能