求1+2+...+n ----《剑指offer》面试题46

题目

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句(A?B:C)。

思路

除了用公式 sum = n(n+1)/2 之外,无外乎循环和递归两种思路。那只能找寻其它方法代替循环与递归。

代码

#include <iostream>

using namespace std;

// ----------   一、利用构造函数求解:1 + 2 + 3 + ... + n

class Temp
{
public:
    Temp() {++N; Sum += N;} //  通过构造函数进行累加

    static void Reset() { N = 0; Sum = 0;}
    static unsigned GetSum() { return Sum;}

private:
    static unsigned N;      //  通过静态成员保存N与Sum
    static unsigned Sum;
};

unsigned  Temp::N = 0;      //  静态成员一定要在外部初始化
unsigned  Temp::Sum = 0;

unsigned Sum_Solution1(unsigned n)
{
    Temp::Reset();

    Temp *a = new Temp[n];  //  累计调用n次构造函数
    delete[](a);
    a = nullptr;            //  防止空悬指针是个好习惯

    return Temp::GetSum();
}



// ----------   二、利用虚函数求解:1 + 2 + 3 + ... + n

class A;
A* Array[2];

//  父类的虚函数相当于终止函数
class A
{
public:
    virtual unsigned  Sum (unsigned n)
    {
        return 0;
    }
};

//  子类的虚函数可以实现递归调用。
//  通过两次取反,使得当n不为0时,一直调用B::Sum,
//  n为0时,调用A::Sum,终止递归。
class B: public A
{
public:
    virtual unsigned Sum (unsigned n)
    {
        return Array[!!n]->Sum(n-1) + n;
    }
};

int Sum_Solution2(int n)
{
    A a;
    B b;
    Array[0] = &a;
    Array[1] = &b;

    int value = Array[1]->Sum(n);   //  先调用B的虚函数

    return value;
}



// ----------   三、利用函数指针求解:1 + 2 + 3 + ... + n

typedef unsigned int (*fun)(unsigned);

unsigned int Solution3_Teminator(unsigned)
{
    return 0;
}

//  想法与第二种方法一样,只是切换的是函数指针,而不是不同的虚函数
unsigned int Sum_Solution3(unsigned n)
{
    static fun f[2] = {Solution3_Teminator, Sum_Solution3};
    return n + f[!!n](n - 1);
}



// ----------   四、利用函数模板求解:1 + 2 + 3 + ... + n

//  让编译器帮助完成类似递归计算
//  Sum_Solution4<100>::N = Sum_Solution4<99>::N + 100
//  Sum_Solution4<1>::N = 1

//  不要把struct写成class了,不然会使得Value成为私有成员
template <unsigned n>
struct Sum_Solution4
{
    enum Value { N = Sum_Solution4<n - 1>::N + n};
};

template <>
struct Sum_Solution4<1>
{
    enum Value { N = 1};
};

int main()
{
    cout << "1 + 2 + 3 + ... + 100" << endl
        << "solution_1: " << Sum_Solution1(100) << endl
        << "solution_2: " << Sum_Solution2(100) << endl
        << "solution_3: " << Sum_Solution3(100) << endl
        << "solution_4: " << Sum_Solution4<100>::N << endl;

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值