求1+2+…+n

题目:求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+…+n
class 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>的结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值