任务:打印从1到1000的数字,不使用任何循环或条件语句。不要只写printf()或cout语句1000次。

用C或c++怎么做呢?


当前回答

很难看透所有已经提出的解决方案,所以这可能是一个重复。

我想要一些相对简单的东西,只有纯C,而不是c++。它使用递归,但与我看到的其他解相反,它只做对数深度的递归。通过查找表可以避免使用条件。

typedef void (*func)(unsigned, unsigned);
void printLeaf(unsigned, unsigned);
void printRecurse(unsigned, unsigned);


func call[2] = { printRecurse, printLeaf };

/* All array members that are not initialized 
   explicitly are implicitly initialized to 0 
   according to the standard. */
unsigned strat[1000] = { 0, 1 };


void printLeaf(unsigned start, unsigned len) {
  printf("%u\n", start);
}

void printRecurse(unsigned start, unsigned len) {
  unsigned half0 = len / 2;
  unsigned half1 = len - half0;
  call[strat[half0]](start, half0);
  call[strat[half1]](start + half0, half1);
}

int main (int argc, char* argv[]) {
  printRecurse(0, 1000);
}

这甚至可以通过使用一个指针动态地完成。相关的变化:

unsigned* strat = 0;

int main (int argc, char* argv[]) {
  strat = calloc(N, sizeof(*strat));
  strat[1] = 1;
  printRecurse(0, N);
}

其他回答

不懂足够的C(++)来写代码,但你可以使用递归而不是循环。为了避免这种情况,可以使用在第1000次访问后抛出异常的数据结构。例如,某种带有范围检查的列表,在每次递归时增加/减少索引。

从评论中判断,c++中似乎没有任何范围检查列表?

相反,你可以用1/n作为递归函数的参数,每次调用都减少1。从1000开始。DivisionByZero异常将停止递归

受到Orion_G的回答和reddit讨论的启发;使用函数指针和二进制算术:

#include <stdio.h>
#define b10 1023
#define b3 7

typedef void (*fp) (int,int);

int i = 0;
void print(int a, int b) { printf("%d\n",++i); }
void kick(int a, int b) { return; }

void rec(int,int);
fp r1[] = {print, rec} ,r2[] = {kick, rec};
void rec(int a, int b) {
  (r1[(b>>1)&1])(b10,b>>1);
  (r2[(a>>1)&1])(a>>1,b);
}

int main() {
  rec(b10,b3);
  return 1;
}

看起来它不需要使用循环

printf("1 10 11 100 101 110 111 1000\n");

被接受答案的c++变体:

void print(vector<int> &v, int ind)
{
    v.at(ind);
    std::cout << ++ind << std::endl;
    try
    {
        print(v, ind);
    }
    catch(std::out_of_range &e)
    {
    }
}

int main()
{
    vector<int> v(1000);
    print(v, 0);
}

除了基本的字符串处理,你真的不需要任何东西:

#include <iostream>
#include <algorithm>

std::string r(std::string s, char a, char b)
{
    std::replace(s.begin(), s.end(), a, b);
    return s;
}

int main()
{
    std::string s0 = " abc\n";
    std::string s1 = r(s0,'c','0')+r(s0,'c','1')+r(s0,'c','2')+r(s0,'c','3')+r(s0,'c','4')+r(s0,'c','5')+r(s0,'c','6')+r(s0,'c','7')+r(s0,'c','8')+r(s0,'c','9');
    std::string s2 = r(s1,'b','0')+r(s1,'b','1')+r(s1,'b','2')+r(s1,'b','3')+r(s1,'b','4')+r(s1,'b','5')+r(s1,'b','6')+r(s1,'b','7')+r(s1,'b','8')+r(s1,'b','9');
    std::string s3 = r(s2,'a','0')+r(s2,'a','1')+r(s2,'a','2')+r(s2,'a','3')+r(s2,'a','4')+r(s2,'a','5')+r(s2,'a','6')+r(s2,'a','7')+r(s2,'a','8')+r(s2,'a','9');
    std::cout << r(r(s1,'a',' '),'b',' ').substr(s0.size())
          << r(s2,'a',' ').substr(s0.size()*10)
          << s3.substr(s0.size()*100)
          << "1000\n";
}