看到这个题,不考虑限定条件,我们可能会有两个方向
1.一个就是用等差数列公式m=n(n+1)/2直接就可以求出来了
2.用循环实现
但是上面都限定了。所以我们就要想办法了
我们知道,多数情况下,循环和递归是可以转换的
那么有这样一种最基本方法,我们用递归实现
#include <stdio.h> #include <iostream> using namespace std; int Get_1_add_to_n(int n) { if(n==1) { return 1; } return n+Get_1_add_to_n(n-1); } int main() { int n=8; int ret=Get_1_add_to_n(n); cout<<ret<<endl; return 0; }
或者这样:
#include <stdio.h> #include <iostream> using namespace std; class AA { public: AA() { _sum=_sum+(++_count); } static int _count;//定义静态数据成员 static int _sum; }; int AA::_count=0;//对静态数据成员进行初始化 int AA::_sum=0; int main() { const int N=10; AA *p=new AA[N]; cout<<AA::_sum<<endl; return 0; }
可是上面的两种方法都不是很优美的解法,因为这样的时间复杂度为O(N),我们是否有一种复杂度为O(1)的解法呢?
我们可以这样想,是否可以将一些操作放在代码编译的时候来做,这样代码运行起来的效率就高了呢。
有人很巧妙的利用到了这一点:
都是别人想的。我只是代码的搬运工:
#include <stdio.h> #include <iostream> using namespace std; int main() { const int N=10; char arr[N][N+1]; char size=sizeof(arr)/sizeof(arr[0][0]);//N*(N+1)为数组的大小 int ret=size>>1;//完美的利用了N(N+1)/2 cout<<ret<<endl; return 0; }
但是这种方法是不能运算比较大的数字的,栈上的空间是有限的,可以自己试一下
还有一种方法是这样的:
#include <stdio.h>
#include <iostream>
using namespace std;
template <int N>
class Sum
{
public:
enum//这里是一个匿名枚举类型
{
RET=N+Sum<N-1>::RET,//递归的去计算N+(N-1)+...+1(不过是在编译时进行展开)
};
};
//全特化
template <>
class Sum<1>//N为1时也是上面递归的出口
{
public:
enum
{
RET=1,
};
};
int main()
{
const int N=10;
cout<<Sum<N>::RET<<endl;
}
特化的概念是继模板提出来的
前面讲过,模板函数有其重载函数时,这时候就会调用重载函数,不会再去进行推演。
这里模板类中的
特化就是不管你调不调用都会生生成代码
template <typename T> class SeqList { public : SeqList(); ~ SeqList(); private : int _size ; int _capacity ; T* _data }; //必须有一个模板类的基础上才会有特化 template <>//全特化没有模板参数 class SeqList <int>//定义类时显示指定模板参数 { public : SeqList(int capacity); ~ SeqList(); private : int _size ; int _capacity ; int* _data ; };
上面举例的时
全特化,还有一种是
偏特化
看看下面的例子:
#include <stdio.h> #include <iostream> using namespace std; template<class T1,class T2> class Data { public: Data() { cout<<"<T1,T2>"<<endl; } }; //*i*****************************全特化************************* template<> class Data<int ,int> { public: Data() { cout<<"<int,int>"<<endl; } }; //*******************************偏特化************************** template<class T2> class Data<char,T2>//对T1进行偏特化 { public: Data() { cout<<"<char,T2>"<<endl; } }; template<class T1> class Data<T1,char>//对T2进行偏特化 { public: Data() { cout<<"<T1,char>"<<endl; } }; template<class T1,class T2> class Data<T1 *,T2 *>//对T1和T2进行偏特化,加限制条件 { public: Data() { cout<<"<*T1,*T2>"<<endl; } }; template<class T1,class T2> class Data<T1 &,T2 &>//对T1和T2进行偏特化,加限制条件 { public: Data() { cout<<"<int,T2>"<<endl; } }; int main() { Data<float,float> d0; Data<int ,int > d1; Data<int ,char> d2; Data<char,int> d3; Data<int *,int *> d4; Data<int &,int &> d5; //Data<char,char> d6; return 0; }再结合上面的求1+2+3+...+N,中的模板中的枚举类型在编译时进行展开的例子来理解特化。