zoukankan      html  css  js  c++  java
  • [原]《面试题精选》09.不用for,while,if等关键字求1+2+...+n

    题目:求1+2+…+n,要求不能使用乘除法、forwhileifelseswitchcase等关键字以及条件判断语句(A?B:C)。


    分析:很显然,这道题的解法非常多,思路大家都知道, 对于解高斯数列和的问题,除了用公式外,无非就是用循环或者递归。但循环要用到for或者while,而递归肯定要用到判断语句,那么就会使用到if。

    说到这大家肯定会认为唯一求解高斯数列和问题的两种方法都不能用,那怎么求。不用急,我们可以利用语言中某些特性来解决循环不用for,判断不用if。这就考察大家对编程语言的熟练程度了。


    解法一:利用0代替bool值特性和&&操作符(递归法)

    这种方法利用了c++中0代替bool值false,来解决递归中的判断问题。java中不行,因为0不能代替bool值

    int addfunc(int i){
    	int sum = 0;
    	i && (sum= i + addfunc(i-1) );
    	return sum;
    }

    解法二:构造函数法(循环法)

    这种方法桥面的利用了c++中类数组的特性,Object[] array = new Object[100] ;类数组new时不仅申请了空间,而且还调用了构造函数,这一点上java是不能的,这就涉及到java和c++数组的区别了,java只是申请了内存空间而不会掉用构造函数,详见:Java/C++中数组的区别

    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];
        delete []a;
        a = NULL;
    
        return Temp::GetSum();
    }


    解法三:虚函数法

    巧妙利用(!!n)来作为数组Array的索引,当n=0时(!!n)=0,n>0时(!!n)=1,我们可以在Array中保存基类和子类,利用虚函数的特性:运行时调用(晚期绑定,动态绑定)

    如果你对虚函数不熟的话,详见:C++中的虚函数,《Thinking in C++》15章里面也讲的很清楚。

    这种方法java也能实现,而且所有非static方法都用到了动态绑定,详见:C++与java的区别,文中第34点。

    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)
        {
            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);
    
        return value;
    }

    解法四:函数指针法

    我们知道在c语言中是没有虚函数的,但是我们也可以用指针函数


    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};
        return n + f[!!n](n - 1);
    }

    解法五:模板类法

    The value of Sum_Solution4<100>::N is the result of 1+2+…+100. When compilers seeSum_Solution4<100>, it will generate code for the template class Sum_Solution4 with parameter 100. A class Sum _Solution4 <99> is needed to generate the classSum_Solution4<100> since Sum _Solution4<100>::N= Sum _Solution4 <99>::N+100. The recursive process stops when it reaches the Sum_Solution4<1> because it has been defined explicitly.

    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};
    };

    总结:虽然这道题有点怪,没太多实际意义,但是很好的考察了你对语言的熟练程度。能让你了解编程语言的很多特性。

    作者:SpeedMe 发表于2014-4-5 22:34:25 原文链接
    阅读:266 评论:1 查看评论
  • 相关阅读:
    hash算法
    TCP/IP四层与OSI七层模型
    di
    VSCode安装程序——java开发
    java中的多线程
    C#ThreadPool类—多线程
    学习-思考
    DataTable通过Select进行过滤
    javascript遍历对象属性
    WebClient 与HttpClient 的区别
  • 原文地址:https://www.cnblogs.com/huanglei/p/3677697.html
Copyright © 2011-2022 走看看