【剑指offer】实现1+2+3+..+n,要求不使用乘除法、循环、判断条件

这道题目的实质是考察程序员的发散思维能力,发散思维能够反映出应聘者知识面的宽度,以及对编程相关技术理解的深度。

拿到这道题时,首先考虑最简便的方法当然是利用等差数列求和公式(n+1)n/2,想要得出结果,无外乎循环和递归两种,但是题目限制了循环,判断条件都不能使用,使用循环时就必须使用循环判断条件,,与条件不符;使用递归时,少不了if条件,这就需要考虑其他的一些路径。

针对这道题目,这里介绍·四种解法,接下来进行逐一介绍:

第一种:利用构造函数求解

实现的方法是将累加相关代码放进构造函数里,通过构造n个对象实现累加的过程

代码如下:

#include<iostream>
#include<stack>
using namespace std;
class Temp
{
public:
	Temp(){ ++N; sum += N; }
	static void reset()
	{
		N = 0;
		sum = 0;
	}
	static int get_sum(){ return sum; }
private:
	static int N;
	static int sum;

};
int Temp::N = 0;
int Temp::sum = 0;
 int AddOne2N(int n)
{
	Temp::reset();
	Temp *a = new Temp[n];
	delete[] a;
	a = NULL;
	return Temp::get_sum();

}

方法二、利用虚函数求解

主要思想是:利用递归,但是不能使用if判断,这里就必须用一个东西来替代这个if判断,这里我们定义两个函数,一个函数充当递归函数的角色,另一个函数处理终止递归的情况,我们需要做的就是在这两个函数中二选一,利用bool变量是我们能想到的第一个办法,非零的转换成true,零转换成false,这里对零使用两次非运算就可实现。

代码如下:

class A;
 A* array[2];
 class A
 {
 public:
	 virtual int sum(int n)
	 {
		 return 0;
	 }
 };
 class B :public A
 {
 public:
	 virtual int sum(int n)
	 {
		 return array[!!n]->sum(n - 1) + n;
	 }

 };
	 int AddOne2N2(int n)
 {
		 A a;
		 B b;
		 array[0] = &a;
		 array[1] = &b;
		 int value = array[1]->sum(n);
		 return value;
	 }

方法三、利用函数指针进行计算

在c语言中,没有虚函数机制,此时可以使用函数指针来模拟实现,其中的主要思想和虚函数类似,而且使用函数更加直观一点,代码如下:

typedef  int (*fun)(int);
	 int solotion3_tmp(int n)
	 {
		 return 0;
	 }
	 int AddOne2N3(int n)
	 {
		 static fun f[2] = { solotion3_tmp, AddOne2N3 };
		 return f[!!n](n-1) + n;
	 }

方法四、使用模板类型求解

代码如下:

 template<int n>
	 struct Sum_Solotion
	 {
		 enum Value{N = Sum_Solotion<n-1>::N+n};
	 };
	 template<>
	 struct Sum_Solotion<1>
	 {
		 enum Value{N = 1};
	 };

Sum_Solotion<100>::N就是1+2+3+...+n的结果,利用编译器直接生成以100为参数的代码,要想生成以100为参数的代码,就需要以99为参数的类型,这样一直递归下去,一直递归到以1为参数的类型,这时以1为参数的类型不用编译器生成,已经显式给出可以直接使用,递归编译到此结束,这里的缺点就是模板参数n是静态的一个数,不能动态给出,只能是一个确定的数值。这就是这种方法的一个缺陷。

到此为止,四种方法均已介绍完毕。

完整代码如下:

#include<iostream>
#include<stack>
using namespace std;
class Temp
{
public:
	Temp(){ ++N; sum += N; }
	static void reset()
	{
		N = 0;
		sum = 0;
	}
	static int get_sum(){ return sum; }
private:
	static int N;
	static int sum;

};
int Temp::N = 0;
int Temp::sum = 0;
 int AddOne2N(int n)
{
	Temp::reset();
	Temp *a = new Temp[n];
	delete[] a;
	a = NULL;
	return Temp::get_sum();

}
 class A;
 A* array[2];
 class A
 {
 public:
	 virtual int sum(int n)
	 {
		 return 0;
	 }
 };
 class B :public A
 {
 public:
	 virtual int sum(int n)
	 {
		 return array[!!n]->sum(n - 1) + n;
	 }

 };
	 int AddOne2N2(int n)
 {
		 A a;
		 B b;
		 array[0] = &a;
		 array[1] = &b;
		 int value = array[1]->sum(n);
		 return value;
	 }
	 typedef  int (*fun)(int);
	 int solotion3_tmp(int n)
	 {
		 return 0;
	 }
	 int AddOne2N3(int n)
	 {
		 static fun f[2] = { solotion3_tmp, AddOne2N3 };
		 return f[!!n](n-1) + n;
	 }
	 template<int n>
	 struct Sum_Solotion
	 {
		 enum Value{N = Sum_Solotion<n-1>::N+n};
	 };
	 template<>
	 struct Sum_Solotion<1>
	 {
		 enum Value{N = 1};
	 };
	
int main()
{
	int n = 0;
	//cout << "please input the number you want" << endl;
	//cin >> n;
	cout << "the final number is:>>";
	//cout << AddOne2N(n) << endl;
	//cout << AddOne2N2(n) << endl;
	//cout << AddOne2N3(n) << endl;
	
	cout << Sum_Solotion<1>::N << endl;
	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值