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

来源:互联网 发布:农业税 知乎 编辑:程序博客网 时间:2024/06/03 19:45
/*- ==========================================================*     文件名  :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, 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返回9856int 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*     修改时间: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//=============
原创粉丝点击