无循环的循环
严格来说不是算法的内容,算是比较性的东西。目标是在特定情况下对序列进行求和
原文于 2020-07-24 写在 CSDN 上的博客上,但是现在转移到此处
无循环求和
无循环,但是可有条件语句,这是可以简单地使用递归或者 goto 语句模拟循环:
使用递归:
int calc(int end) {
if(!end) return 0;
return end + calc(end - 1);
}
使用 goto:
int calc(int end) {
int sum = 0;
num:
if(!end) return sum;
sum += end;
--end;
goto num;
}
无循环和无条件语句
这种情况下最简单的应该是 C++ 的模板,通过模板特化实现终止递归:
template<int end>
int calc() {
return end + calc<end - 1>();
}
template<>
int calc<0>() {
return 0;
}
其次还可以使用逻辑表达式短路的方式:
int calc(int end) {
static int sum = 0;
sum += end;
end&& calc(end - 1);
return sum;
}
或者是通过数组特化的方式:
typedef int (*pCalc)(int);
int yescalc(int);
int nocalc(int);
pCalc dispatch[] = {
yescalc,
nocalc,
};
int yescalc(int end) {
return end + dispatch[end == 0](end - 1);
}
int nocalc(int i) {
return 0;
}
也可以通过函数指针的特化实现这一点:
int zero(int i) {
return 0;
}
int calc(int end) {
return end + (calc + (zero - calc) * (end == 0))(end - 1);
}
上面的代码只能在 C 中执行,因为 C++ 11 禁止函数指针之间的运算。尽管可以通过类型转换达到效果,但是代码就失去了简洁性。
打印数字
与上面条件相同,但是要求只是用来打印而不是求和,因此能使用更多黑魔法:
使用宏
#define A(x) x;x;x;x;x;x;x;x;x;x;
int main(){
int i = 1;
A(A(A(printf("%d ", i++))));
return 0;
}
这个方法是网上找到的,不知道为什么网上转载的宏定义都不完整。
A(x) 等于是连续执行 10 次 x 代表的语句。A(A(A())) 等于是连续嵌套三次,执行 1 0 3 10^3 103 次 x 代表的语句。
使用构造函数:
class A {
public:
A() {
static int N = 1;
cout << N++ << ' ';
}
};
int main() {
new A[1000];
return 0;
}
使用迭代器:
#include <iterator>
class number_iterator{
int value;
public:
typedef std::input_iterator_tag iterator_category;
typedef int value_type;
typedef std::size_t difference_type;
typedef int* pointer;
typedef int& reference;
number_iterator(int v): value(v){}
bool operator!=(number_iterator const& rhs){
return value != rhs.value;
}
number_iterator operator++(){
++value;
return *this;
}
int operator*(){
return value;
}
};
int main()
{
std::copy(number_iterator(1),
number_iterator(1001),
std::ostream_iterator<int>(std::cout," "));
}
使用生成器:
int num() {
static int i = 1; return i++;
}
int main() {
generate_n(ostream_iterator<int>(cout," "), 1000, num);
}