zoukankan      html  css  js  c++  java
  • 《剑指offer》第六十四题:求1+2+…+n

    // 面试题64:求1+2+…+n
    // 题目:求1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case
    // 等关键字及条件判断语句(A?B:C)。
    
    #include <cstdio>
    
    // ====================方法一====================
    // 利用构造函数求解
    class Temp
    {
    public:
        Temp() { ++N; Sum += N; }
    
        static void Reset() { N = 0; Sum = 0; }
        static unsigned int GetSum() { return Sum; }
    
    private:
        //静态成员, 所有实例共享
        static unsigned int N;  //当前数
        static unsigned int Sum; //累加和 
    };
    
    unsigned int Temp::N = 0;
    unsigned int Temp::Sum = 0;
    
    unsigned int Sum_Solution1(unsigned int n)
    {
        Temp::Reset();  //初始化
    
        Temp* a = new Temp[n];  //创建n个实例, 则构造函数会被调用n次
        delete[] a;
        a = nullptr;
    
        return Temp::GetSum();
    }
    
    // ====================方法二====================
    // 使用虚函数求解
    class A;
    A* Array[2];
    
    class A
    {
    public:
        virtual unsigned int Sum(unsigned int n) //处理函数中止
        {
            return 0;
        }
    };
    
    class B : public A
    {
    public:
        virtual unsigned int Sum(unsigned int n)  //充当递归函数
        {
            // !!n 非零值为true 零值为false
            return Array[!!n]->Sum(n - 1) + n;
        }
    };
    
    int Sum_Solution2(int n)
    {
        A a;
        B b;
        Array[0] = &a;
        Array[1] = &b;
    
        //当n大于0时, 总是执行B中sum, 直到n==0
        int value = Array[1]->Sum(n);
    
        return value;
    }
    
    // ====================方法三====================
    // 利用函数指针求解
    typedef unsigned int (*fun)(unsigned int);
    
    unsigned int Solution3_Teminator(unsigned int n)
    {
        return 0;
    }
    
    unsigned int Sum_Solution3(unsigned int n)
    {
        //静态成员, 实现方法类似于方法二
        static fun f[2] = { Solution3_Teminator, Sum_Solution3 }; //两个函数
    
        //当n大于0时调用函数Sum_Solution3
        //当n==0时调用函数Solution3_Teminator
        return n + f[!!n](n - 1); 
    }
    
    // ====================方法四====================
    // 利用模板类型求解
    template <unsigned int n> struct Sum_Solution4
    {
        //实现方法类似
        enum Value { N = Sum_Solution4<n - 1>::N + n };
    };
    
    template <> struct Sum_Solution4<1>
    {
        enum Value { N = 1 };
    };
    
    template <> struct Sum_Solution4<0>
    {
        enum Value { N = 0 };
    };
    // ====================测试代码====================
    void Test(int n, int expected)
    {
        printf("Test for %d begins:
    ", n);
    
        if (Sum_Solution1(n) == expected)
            printf("Solution1 passed.
    ");
        else
            printf("Solution1 failed.
    ");
    
        if (Sum_Solution2(n) == expected)
            printf("Solution2 passed.
    ");
        else
            printf("Solution2 failed.
    ");
    
        if (Sum_Solution3(n) == expected)
            printf("Solution3 passed.
    ");
        else
            printf("Solution3 failed.
    ");
    }
    
    void Test1()
    {
        const unsigned int number = 1;
        int expected = 1;
        Test(number, expected);
        if (Sum_Solution4<number>::N == expected)
            printf("Solution4 passed.
    ");
        else
            printf("Solution4 failed.
    ");
    }
    
    void Test2()
    {
        const unsigned int number = 5;
        int expected = 15;
        Test(number, expected);
        if (Sum_Solution4<number>::N == expected)
            printf("Solution4 passed.
    ");
        else
            printf("Solution4 failed.
    ");
    }
    
    void Test3()
    {
        const unsigned int number = 10;
        int expected = 55;
        Test(number, expected);
        if (Sum_Solution4<number>::N == expected)
            printf("Solution4 passed.
    ");
        else
            printf("Solution4 failed.
    ");
    }
    
    void Test4()
    {
        const unsigned int number = 0;
        int expected = 0;
        Test(number, expected);
        if (Sum_Solution4<number>::N == expected)
            printf("Solution4 passed.
    ");
        else
            printf("Solution4 failed.
    ");
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        Test4();
    
        return 0;
    }
    测试代码

    分析:通过各种方法实现递归操作。

    typedef int (*fun)( int );
    class Solution {
    public:
        
        static int Solution3_Teminator(int n) { return 0; }
        
        static int Sum_Solution(int n) {
            
            static fun f[2] = {Solution3_Teminator, Sum_Solution};
            return n + f[!!n](n - 1);
        }
    };
    牛客网提交代码
  • 相关阅读:
    机器学习算法的流程总结
    机器学习算法的流程总结
    路由器的原理
    路由器的原理
    机器学习编程接口(api)设计(oop 设计)
    机器学习编程接口(api)设计(oop 设计)
    组态档(configuration file)与建构档
    组态档(configuration file)与建构档
    学习之法 —— 套路
    学习之法 —— 套路
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12694308.html
Copyright © 2011-2022 走看看