题目:求1+2+…+n,
要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
思路一:换个思路,定义两个函数,一个函数充当递归函数的角色,另一个函数处理终止递归的情况,我们需要做的就是在两个函数里二选一,从二选一我们很自然的想到布尔变量,比如ture/(1)的时候调用第一个函数,false/(0)的时候调用第二个函数;
那现在的问题是如何把数值变量n转换成布尔值,这是解决问题的关键,解决方案是:对变量n连续做两次逻辑取反运算,即!!n,那么非零的n将变为true,0转变为false。
#include<iostream>
using namespace std;
//功能:求1+2+…+n
typedef int (*PF_Fun) (int nValue);
PF_Fun paFun[2];
int GetSum1(int nValue)
{
return 0;
}
int GetSum2(int nValue)
{
return (*paFun[!!nValue])(nValue - 1) + nValue;
}
int GetValue2(int nValue)
{
paFun[0] = GetSum1;
paFun[1] = GetSum2;
int nSum = GetSum2(nValue);
return nSum;
}
int main()
{
cout << GetValue2(100) << endl;
return 0;
}
虚函数处理:
当然这里也可以使用虚函数的特性来处理这样的问题,具体代码如下:
//功能:求1+2+…+n
class C_Num;
C_Num* paNum[2];
class C_Num
{
public:
virtual int GetSum (int nValue) { return 0; }
};
class C_NumEx: public C_Num
{
public:
virtual int GetSum(int nValue) { return paNum[!!nValue]->GetSum(nValue-1) + nValue; }
};
int GetValue2(int nVal)
{
C_Num objNum;
C_NumEx objNumEx;
paNum[0] = &objNum;
paNum[1] = &objNumEx;
//利用虚函数的特性,当paNum[1]为0时,即paNum[0] = &objNum; 执行C_Num::GetSum,
//当Array[1]不为0时, 即paNum[1] = &objNumEx; 执行C_NumEx::GetSum。
int nSum = paNum[1]->GetSum(nVal);
return nSum;
}
int main()
{
cout << GetValue2(100) << endl;
return 0;
}
思路二:类的构造函数
构造函数执行并且只执行一次,况且题目是N个连续的数相加,可以这样来解:
先定义一个类,然后我们new 一含有n 个这种类型元素的数组,那么该类的构造函数将确定会被调用n 次。
//功能:求1+2+…+nclass C_Number
{
public:
C_Number()
{
++ms_nValue;
ms_nSum += ms_nValue;
}
static void Reset() { ms_nValue = 0; ms_nSum = 0; }
static int GetSum() { return ms_nSum; }
private:
static int ms_nValue;
static int ms_nSum;
};
int C_Number::ms_nValue = 0;
int C_Number::ms_nSum = 0;
int GetValue(int nVal)
{
C_Number::Reset();
C_Number *pNum = new C_Number[nVal];
delete [] pNum;
pNum = 0;
return C_Number::GetSum();
}
int main()
{
cout << GetValue(100) << endl;
return 0;
}
本人理解:还可以直接去掉 GetValue函数,
main函数中直接书写如下代码即可:
const int n=100;//不能使用static,因为arr的大小必须是编译期常量
C_Number arr[n] ;
cout << C_Number::GetSum()<< endl;
思路三:
利用模板元编程实现。
//功能:求1+2+…+n
template <unsigned N> //注意:调用时,N必须为编译器常量
class C_Num
{
public:
enum { m_Value = N + C_Num<N - 1>::m_Value};
};
template< >
class C_Num<1>
{
public:
enum { m_Value = 1};
};
int main()
{
cout << C_Num<100>::m_Value << endl;
return 0;
}
以上原文链接:http://blog.csdn.net/yuucyf/article/details/6400601
扩展:类似的方法还可以求N!,3^n等等
----------------------------------------------------------------------
其他模板元编程例子:
1-递归求阶乘
模板元编程:编译期得到结果
步骤:
1-递归模板具现化实现循环
template<unsigned n>
struct factorial{
enum{value =n*factorial<n-1>::value};
};
2-模板特化结束循环
template<>
struct factorial<0>{
enum {value=1};
};
调用factorial<n>::value
调用factorial<10>::value
2- 求3的N次方
原理
模板元编程的工作:递归的模板实例化
计算3^N的递归模板实例化应用以下2个规则:
1.3^N=3*3^(N-1)
2.3^0=1
枚举值实现
Step1:第1个模板实现一般的递归原则
template<int N>
class pow1{
public:
enum{result=3*pow3<N-1>::result};
};
Step2:第2个模板结束递归的特化,确定pow3<0>的结果
template< >
class pow1<0>{
public:
enum{result=1};
};
效果:调用pow3<7>::result
编译器实例化pow3<7>,获得3*pow3<6>::result
实例化pow3<6>,获得3*pow3<5>::result
类似的,递归不断进行,直到pow3<>基于0进行实例化,递归结束,
1作为pow3<7>的结果