多项式方程实根

//2005.3 杭州

#ifndef PolyEquation_Header

#define PolyEquation_Header

 

#include <cassert>

#include <vector>

#include <cmath>

#include <algorithm>

 

#define MAXRESULT 1e10

#define MINRESULT -1e10

#define EPSILON   1e-6

 

using namespace std;

 

template<typename T>

class PolyEquation

{

public:

     PolyEquation(int _N):N(_N)

     {

         coe.reserve(N+1);

     }

     template<typename T1>

         PolyEquation(const T1 &pVal,int _N):N(_N)

     {

         coe.reserve(N+1);

         for (int i=0;i<N+1;i++)

         {

              coe.push_back(pVal[i]);

         }

     }

     T GetValue(T _Val)

     {

         T tmp1=0;

         for (int i=0;i<N+1;i++)

         {

              T tmp2=1.0;

              for (int j=0;j<i;j++)

              {

                   tmp2*=_Val;

              }

              tmp1+=coe[N-i]*tmp2;

         }

         return tmp1;

     }

     PolyEquation<T> GetDPoly()

     {

         assert(N>1);

         vector<T> tmp1;

         for (int i=0;i<N;i++)

         {

              tmp1.push_back(coe[i]*(N-i));

         }

         return PolyEquation<T>(tmp1,N-1);

     }

 

     vector<T> GetRealSolve()

     {

         vector<T> tmp1;

         if(N==0)

         {

              return tmp1;

         }

         if(N==1)

         {

 

              if(coe[0]!=0)

              {

                   tmp1.push_back(coe[1]/coe[0]);

              }

              return tmp1;

         }

         if(N==2)

         {

              if(coe[0]!=0)

              {

                   if ((coe[1]*coe[1]-coe[0]*coe[2]*4.0)>=0)

                   {

                       tmp1.push_back((-coe[1]+sqrt(coe[1]*coe[1]-coe[0]*coe[2]*4.0))/(2.0*coe[0]));

                       tmp1.push_back((-coe[1]-sqrt(coe[1]*coe[1]-coe[0]*coe[2]*4.0))/(2.0*coe[0]));

                   }

              }

              else

              {

                   vector<T> tmp2;

                   tmp2.push_back(coe[1]);

                   tmp2.push_back(coe[2]);

                   PolyEquation<T> tmp3(tmp2,1);

                   return tmp3.GetRealSolve();

              }

              return tmp1;

         }

         vector<T> tmp2=GetDPoly().GetRealSolve();

         int N2=tmp2.size();

         if (N2>0)

         {

              sort(tmp2.begin(),tmp2.end());

              DivSol(MINRESULT,tmp2[0],tmp1);

              DivSol(tmp2[N2-1],MAXRESULT,tmp1);

              if(N>1)

              {

                   for (int i=0;i<N-1;i++)

                   {

                       DivSol(tmp2[i],tmp2[i+1],tmp1);

                   }

              }

         }

         else

         {

              DivSol(MINRESULT,MAXRESULT,tmp1);

         }

         return tmp1;

     }

     void DivSol(T Val1,T Val2,vector<T> &Res)

     {

         if (fabs(Val2-Val1)<EPSILON)

         {

              Res.push_back(Val1);

              return;

         }

         T tmp1=GetValue(Val1);

         T tmp2=GetValue(Val2);

         T tmp3=GetValue((Val1+Val2)/2.0);

         if(fabs(tmp1)<EPSILON)

         {

              Res.push_back(Val1);

              return;

         }

         if(fabs(tmp2)<EPSILON)

         {

              Res.push_back(Val2);

              return;

         }

         if( (tmp1>0 && tmp2>0) || (tmp1<0 && tmp2<0) )

         {

              return;

         }

         if (fabs(tmp3)<EPSILON)

         {

              Res.push_back((Val1+Val2)/2.0);

              return;

         }

         if ( (tmp1>0 && tmp3<0) || (tmp1<0 && tmp3>0))

         {

              DivSol(Val1,(Val1+Val2)/2.0,Res);

         }

         if ( (tmp2>0 && tmp3<0) || (tmp2<0 && tmp3>0))

         {

              DivSol(Val2,(Val1+Val2)/2.0,Res);

         }

     }

private:

     int N;

     vector<T> coe;

};

 

#endif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值