剑指offer---不使用循环条件判断等实现求和

17 篇文章 0 订阅
17 篇文章 1 订阅

题目描述:求1+2+3+....+n,要求不使用乘除法,for,while,if,else,switch,case

等关键字及三目表达式。

题目分析:由于不能使用条件判断的关键字,所以,一般的递归也是不允许的,因为通过

条件判断来确定递归是否结束。但是下边的方法有模仿递归来实现求和。

方法一:构造函数

由于静态成员是属于类而不属于对象,根据这一特性,来实现求和。

下边给出代码:

class Sum
{
public:
	Sum()
	{
		++n;
		sum += n;
	}
	static void ShowSum()//必须是静态成员函数
	{
		cout << sum << endl;
	}
private:
	static size_t sum;
	static size_t n;
};
size_t Sum::sum = 0;
size_t Sum::n = 0;
int main()
{
	Sum* a = new Sum[100];
	delete[] a;
	a = NULL;
	Sum::ShowSum();
	system("pause");
	return 0;
}


我们知道静态成员是属于类不属于对象,所以静态成员方法无this指针;

静态成员必须在类外进行初始化;

静态方法中不能调用非静态成员变量(解释:返回的时候不知道返回哪个变量的成员)

方法二:虚函数

下边看代码:

class A
{
public:
	virtual size_t Sum(size_t n)
	{
		return 0;
	}
};
A* Array[2];
class B :public A
{
public:
	virtual size_t Sum(size_t n)
	{
		return Array[!!n]->Sum(n - 1) + n;
	}
};
int main()
{
	A a;
	B b;
	Array[0] = &a;
	Array[1] = &b;
	int sum = Array[1]->Sum(100);
	cout << sum << endl;
	system("pause");
	return 0;
}


这里用到动态多态。实现多态的标志就是父类指针或者引用指向子类对象。当n>=1时,

!!n都是1.当n=0时,!!n=0.这就是“!!的用途。父类的虚函数充当着递归结束的条件。

......当递归到n = 1时,Array[1]->Sum(0)+1.而Sum(0) = Array[0]->Sum(-1) = 0.


<小插曲>说到虚函数,说到多态,不由得想到下边这道题目(以分割线分隔开):

-------------------------------------------------------------------------------------------------------

代码如下:

class AA
{
public:
	AA()
	{
		memset(this,0,sizeof(*this));
	}
	virtual void fun()
	{
		cout << "fun()" << endl;
	}
};
int main()
{
	AA a;
	a.fun();

	AA& ra = a;
	ra.fun();

	AA* pa = &a;
	pa->fun();
	system("pause");
	return 0;
}


问题是,以上的几个调用语句,哪个编译通过,哪个不通过?

a.fun()调用正确,其他两个都不正确。

解析:构造函数的memset会将函数的虚表指针置为空。而a.fun()是静态多态,调用的时

候并不会去虚表中找,所以是会调用通过。后边两个调用是动态多态,调用的时候会去

虚表中找,而虚表指针已经被置空。所以,在构造函数中尽量不要使用memset等函数.

----------------------------------------------------------------------------------------------------------------

方法三:函数指针:

typedef size_t(*fun)(size_t);
size_t sum1(size_t n)
{
	return 0;
}
size_t sum2(size_t n)
{
	fun f[2] = { sum1,sum2 };
	return n + f[!!n](n-1);
}
int main()
{
	cout<<sum2(100)<<endl;
	system("pause");
	return 0;
}


上边的方法类似于虚函数实现。

方法四:模板

template<size_t n>
struct Sum
{
	enum Value
	{
		N = Sum<n - 1>::N + n
	};
};
template<>
struct Sum<1>
{
	enum Value
	{
		N = 1
	};
};
int main()
{
	cout << Sum<100>::N << endl;
	system("pause");
	return 0;
}


上述方法利用的是模板的特化来实现对“递归”结束的控制。

好了,这道题目就整理到这里。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值