自然数1-n,不使用循环和分支语句的相关问题

本文探讨了如何在不使用循环和条件语句的情况下解决两个经典问题:输出1到n的整数及计算1到n的累加和。通过巧妙运用C++特性,如静态成员变量、宏定义、递归与多态,提供了创新解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


今天看到了一个题目,又想起了以前的一个题目,这两个题目也算是有相关性吧。在这里总结一下。


题目1:不使用分支语句,循环语句,如:for while switch if goto 等关键字,输出1-n的整数。

题目2:求1+2+....n,要求不能使用乘除法、for、while、if、else、switch、case等关键字。

这两个题目的相关性就是不让使用循环和分支语句,这就是难点所在。对于题目1,我想到的就是静态成员变量,因为静态成员变量在内存中只有一份,所以可以共享,如果在这里用递归的话,最大的难点就是递归的出口怎么定义。目前,我没有想到可行的递归的方法。要使用静态成员变量,还有一个可行的方法那就是在类中来使用,我们可以通过不同的对象来实现内存中共享的静态成员变量的自增,从而输出1-n的自然数。如下是代码:

class D
{
public:
	D()
	{
		cout << ++n << " ";
	}
private:
	static int n;
};
int D::n = 0;

void main()
{
	D arr[100];
}

对于题目1,还有一个解法就是用宏定义。因为宏只是简单的代入,所以我们可以利用这点性质来实现嵌套输出1-n的自然数。例如:我们输出1-1000,代码如下:

#define A(x) x;x;x;x;x;x;x;x;x;x
void main()
{
	int n = 0;
	A(A(A(printf("%d ",++n))));
}

对于题目2,有了题目1的解,我们应该会有一个大概的思路。经上面的提示,我们应该会想到静态变量的应用,而且也是在类中,我们需要两个静态变量,一个用来保存自增的自然数,一个用来保存随时变化的和,这样我们就可以达到目的。代码如下:

class A
{
public:
	A()
	{
		n++;
		sum += n;
	}
	static int GetSum()
	{
		return sum;
	}
private:
	static int n;
	static int sum;
};
int A::n = 0;
int A::sum = 0;
void main()
{
	int n  = 100;
	A *p = new A[n];
	int value = A::GetSum();
	cout << value << endl;
}

题目2的另一种解法,真是让我觉得算法真的太精妙了。这也是看了July的文章后,才知道的这种解法。我根本就想不到这种方法。

重复一下这个思想吧。还是用递归,但是递归的难点就是出口怎么控制。在这里我们定义了两个函数,一个用来递归计算加和,另一个函数用来控制递归的函数出口。那就有两种情况,所以要二选一,那么我们可以用bool变量来控制。怎么根据给定的一个整数n来判断true和false呢?我们知道,如果n不是0,那么n就代表true,!n就表示false,那么!!n就表示true。当n是0时,正好相反。这就是关键所在,我们可以利用这点来控制递归函数出口。代码如下:

class B
{
public:
	virtual int sum(int n)
	{
		return 0;
	}
};
B *arr[2];
class C : public B
{
public:
	virtual int sum(int n)
	{
		return arr[!!n]->sum(n-1) + n;
	}
};
void main()
{
	B b;
	C c;
	int n = 100;
	arr[0] = &b;
	arr[1] = &c;
	int value = arr[1]->sum(n);
	cout << value << endl;

}

上面用到了虚函数,这就是强大之处。多态竟然在这里用上了!我们用一个数组arr[2]保存两个变量,一个是类B的对象的指针,另一个是B类的子类的对象的指针。arr[1]->sum(n),就会调用C类中的sum函数,这里就实现了递归,当n递减到0时,由于!!0就是false,也就是0,那么arr[0]->sum()就会调用B类中的sum函数,此函数实现了递归的结束,也就是递归的出口。从而,我们利用多态实现了1-n的自然数的和。

题外话,这种思想,那是得多么精通c++的人才能想出来啊,自己太菜了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值