最近遇到这样一个问题:求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
经过思考,我发现问题的关键在于:如何不使用条件判断语句,达到条件判断的目的
因此,总结了以下4种方法(以简单的C++为例进行说明)
方法1、利用逻辑运算符的短路特性
众所周知,逻辑运算符&&具有短路特性,即对于a&&b,在a为假时,b不再被计算。因此我们可以将一个函数放在b的位置,将a设置为我们需要的条件,当条件不满足时,不再调用b处的函数,以下为具体的代码:
#include <iostream>
int sum(int n) {
int result = n;
n && (result += sum(n - 1));
return result;
}
int main() {
int total = sum(5);
std::cout << "Sum of 1 to 5 is: " << total << std::endl;
return 0;
}
方法2、利用数组下标‘0’和函数指针(函数指针数组)
不难发现,问题可以简化为,我们需要设计一个开关,当条件发生变化(由false变为true或者由true变为false)时,切换为不同的行为,由此可以想到把一个判断条件放在数组下标方括号内(因为数组下标可以分为两种:0和非0)。具体实现如下:
#include <iostream>
int end_condition(int n) {
return 0;
}
int add(int n) {
static int (*func[])(int) = {end_condition, add};
return n + func[!!n](n - 1);
}
int main() {
int total = add(5);
std::cout << "Sum of 1 to 5 is: " << total << std::endl;
return 0;
}
方法3、模版元编程
当条件发生变化时,切换为不同的行为,由此亦可以联想到模版特化中的对非模版类型的全特化:(提供两种方法,类模版的全特化和函数模版的全特化)
#include <iostream>
template<int n>
struct Sum {
enum { value = n + Sum<n - 1>::value };
};
template<>
struct Sum<0> {
enum { value = 0 };
};
int main() {
std::cout << "Sum of 1 to 5 is: " << Sum<5>::value << std::endl;
return 0;
}
template<int n>
int sum() {
return n + sum<n - 1>();
}
template<>
int sum<0>() {
return 0;
}
int main() {
std::cout << "Sum of 1 to 5 is: " << sum<5>() << std::endl;
return 0;
}
方法4、使用类的构造函数和静态成员变量
由于C++中提供了new这样的自动调用类构造函数的接口,因此可以通过调整类的构造函数和静态成员变量,实现每实例化一个类,完成一次计算:
#include <iostream>
class Sum {
public:
static int total;
static int n;
Sum() {
++n;
total += n;
}
static void reset() {
total = 0;
n = 0;
}
static int calculate(int num) {
reset();
Sum* arr = new Sum[num];
delete[] arr;
return total;
}
};
int Sum::total = 0;
int Sum::n = 0;
int main()
{
int total = Sum::calculate(5);
std::cout << "Sum of 1 to 5 is: " << total << std::endl;;
}
如果各位有其他更好的解决方法或建议,欢迎在评论区分享和提出