无循环的循环

严格来说不是算法的内容,算是比较性的东西。目标是在特定情况下对序列进行求和

原文于 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);
}
Last moify: 2022-12-04 15:11:33
Build time:2025-07-18 09:41:42
Powered By asphinx