#include <iostream> #include <type_traits> #include <vector> #include <initializer_list> #include <typeinfo>
enum:int { MAXVALUE=999 }; template<typename T=double, typename Ty=double, typename Type=double> class BestTree{ private: T** root;//记录给定子树的根节点. Ty** e;//记录子树概率总和. Type** w;//记录子树代价总和. std::vector<Ty> p; std::vector<Type> q; int pLength; public: template<typename X=double, typename Y=double> BestTree(const std::initializer_list<X>& _p, const std::initializer_list<Y>& _q);//这里的_p指的是每个关键字概率的集合, _q是每个伪关键字集合. ~BestTree(); void OptimalBST(); void Subtree(); };
template<typename T, typename Ty, typename Type> template<typename X, typename Y> BestTree<T, Ty, Type>::BestTree(const std::initializer_list<X>& _p, const std::initializer_list<Y>& _q) :p(_p), q(_q) { std::cout<<"test"<<std::endl; if(typeid(T)!=typeid(X) || typeid(Ty)!=typeid(Y) || typeid(Type) != typeid(Y)){ //当与我们所需要的类型不一样的时候会抛出异常. throw std::bad_cast(); } std::cout<<"test"<<std::endl; this->pLength=_q.size(); root=new X*[pLength];//创建一个二维数组[pLenght][pLenght]; for(int i=0; i<pLength; ++i){ root[i]=new X[pLength]; } for(int i=0; i<pLength; ++i){ for(int j=0; j<pLength; ++j){ this->root[i][j]=T(0); } } e=new Y*[pLength+1];//仍然是为了创建一个二维数组。 w=new Y*[pLength+1];//只有当T,Ty类型与Y相同的时候才会构造成功. for(int i=0; i<pLength+1; ++i){ e[i]=new Y[pLength]; w[i]=new Y[pLength]; } typename std::initializer_list<Y>::iterator iterB=_p.begin(); //typename std::initializer_list<Y>::iterator iterE=_p.end(); for(int i=0; i<pLength+1; ++i){ for(int j=0; j<pLength; ++j){ w[i][j]=T(0); e[i][j]=T(0); } } for(int m=1; m<pLength+1; ++m){ e[m][m-1]= *(iterB+m-1); w[m][m-1]= *(iterB+m-1); } std::cout<<"success"<<std::endl; }
template<typename T, typename Ty, typename Type> void BestTree<T, Ty, Type>::OptimalBST() { std::cout<<"enter"<<std::endl; for(int l=1; l<this->pLength+1; ++l){ //用来计算1 <= i <= j <= n之间的值. for(int i=1; i<this->pLength-l+1; ++i){ int j=i+l-1; //j的值为1, 2, 3, 4.... this->e[i][j]=MAXVALUE; //假设的最大值.其实就是令e[i][i]=MAXVALUE; this->w[i][j]=w[i][j-1]+p[j]+q[j]; //其实是w[i][i-1]. for(int k=i; k<j+1; ++k){ //只有当i=2的时候才开始进入循环. T t=e[i][k-1]+e[k+1][j]+w[i][j]; //这里计算出的是i-j之间的值k是作为分割点的.(按照算法导论来说就是做为子树的根节点.) if(t < e[i][j]){ e[i][j]=t; root[i][j]=k; } } } } }
template<typename T, typename Ty, typename Type> void BestTree<T, Ty, Type>::Subtree() { for(int i=0; i<pLength; ++i){ for(int j=0; j<pLength; ++j){ std::cout<<this->root[i][j]<<" "; } std::cout<<std::endl; } }
template<typename T, typename Ty, typename Type> BestTree<T, Ty, Type>::~BestTree() { if(root != nullptr && w != nullptr && e != nullptr){ for(int i=0; i<pLength; ++i){ delete[] root[i]; } delete[] root; for(int i=0; i<pLength+1; ++i){ delete[] w[i]; delete[] e[i]; } delete[] w; delete[] e; } p.clear(); q.clear(); }
int main() { BestTree<> myTree( {double(-1), 0.15, 0.1, 0.05, 0.1, 0.2}, {0.05, 0.1, 0.05, 0.05, 0.05, 0.1}); //注意此处用double(-1),因为模板是不能进行隐式的类型转换的.可以理解为 vector<int> != vector<double>; myTree.OptimalBST(); myTree.Subtree(); return 0; }