zoukankan      html  css  js  c++  java
  • 算法系列:如何不使用循环和判断语句实现“打印从1到100之间的数字”

    声明:翻译仅以技术学习和交流为目的,如需转载请务必标明原帖链接。
    来源:http://stackoverflow.com/questions/4568645/printing-1-to-1000-without-loop-or-conditionals
    水平有限,如有翻译不当,欢迎探讨、批评与指正。

    任务:
    不使用循环和条件判断语句“打印从1到100之间的数字”。不要使用 1000 个printf 或者 cout 哦,O(∩_∩)O~。
    如果是你,你将怎么用 C 或者 C++ 语言实现呢?

    方法一:

    复制代码
    #include <iostream>

    template<int N>
    struct NumberGeneration
    {
    static void out(std::ostream& os)
    {
    NumberGeneration<N-1>::out(os);
    os << N << std::endl;
    }
    };

    template<>
    struct NumberGeneration<1>
    {
    static void out(std::ostream& os)
    {
    os << 1 << std::endl;
    }
    };

    int main()
    {
    NumberGeneration<1000>::out(std::cout);
    }
    复制代码

    译者注:这是利用模板编译时的递归来实现的,会消耗编译时间。存在一个问题就是,不同的编译器对模板递归编译的层数有限制。这个问题,有人跟帖也说了。默认情况下 g++ 的递归深度是 500. 我用 Code::blocks 10.05 和 visual studio 2010 分别进行测试,CB 编译失败,VS2010可成功编译和运行。把参数改成 501 之后(也就是说递归编译层数是500),CB也可以成功编译和运行。

    方法二:

    复制代码
    #include<stdio.h>

    int b = 1;

    int printS()
    {
    printf("%d ", b);
    b++;
    return (1001-b) && printS();
    }

    int main()
    {
    printS();
    }
    复制代码

    方法三:
    OpenMP 版(非命令行方式):

    复制代码
    #include <iostream>
    #include <omp.h>

    int main(int argc, char** argv)
    {
    #pragma omp parallel num_threads(1000)
    {
    #pragma omp critical
    {
    std::cout << omp_get_thread_num() << std::endl;
    }
    }

    return 0;
    }
    复制代码

    (在VS2010 OpenMP 运行时库下无法执行(64个线程的限制),在linux下可以运行,比如 Inter 编译器)。
    下面是一个命令行方式的版本:

    复制代码
    #include <stdio.h>
    #include <omp.h>

    int main(int argc, char *argv[])
    {
    int i = 1;
    #pragma omp parallel num_threads(1000)
    #pragma omp critical
    printf("%d ", i++);
    return 0;
    }
    复制代码

    译者注:我没有接触过 OpenMP ,不敢妄加揣测。如果有熟悉的朋友可以帮忙测试一下,测试完把结果告诉我一下,不胜感激。

    方法四:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>

    int numbers[501] = {0};

    int comp(const void * a, const void * b){
    numbers[0]++;
    printf("%i ", numbers[0]);
    return 0;
    }

    int main()
    {
    qsort(numbers+1,500,sizeof(int),comp);
    comp(NULL, NULL);
    return 0;
    }
    复制代码

    译者注:原帖参数是 51,我想应该是 501。
    想搞懂原因,就要去分析这里面的 qsort 是怎么执行的,
    假设我们要打印1~5,numbers初始序列应该是:0,0,0,0,0,0,程序中实现的是第一个元素的递增,每次比较的时候,打印第一个元素。也就是说其实打印到那个值,取决于调用 comp 的次数。假设qsort选取第一个元素为轴,那么比较次数应该是 4+3+2=9,加上 main 函数中,qsort执行后的一次 comp 调用,4+3+2+1=10。假如轴的选取不是第一个元素,那么比较次数应该是多少呢?读者自己分析吧。

    方法五:

    printf("打印从1到100之间的数字");

    译者注:这个答案亮,但是谁能说它是错的呢?!

    方法六:

    复制代码
    #include <iostream>
    #include <stdexcept>
    #include <cstdio>

    using namespace std;

    int main(int arg)
    {
    try
    {

    printf("%d ",arg);
    int j=1/(arg-1000);
    main(arg+1);
    }

    catch(...)
    {
    exit(1);
    }
    }
    复制代码

    译者注:code::blocks 10.05 不能通过编译(VS2010可以),很显然是因为 exit 的缘故,去掉就可以了。这种方法靠除 0 错引起异常,结束递归,以程序的崩溃而告终,^_^。

    方法七:

    复制代码
    #include <iostream>

    static int n = 1;
    class number
    {
    public:
    number ()
    {
    std::cout << n++ << std::endl;
    }
    };

    int main(int argc, char* argv[])
    {
    number X[1000];
    return 0;
    }
    复制代码

    方法八:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>

    static int x(/*@unused@*/ const char * format, ...)
    {
    exit(0);
    }

    static void p(int v, int e) {
    static int (*a[])(const char *, ...) = { printf, x };
    (void)a[v/(e+1)]("%d ", v);
    p(v+1, e);
    }

    int main(void) {
    p(1, 1000);
    return 0;
    }
    复制代码

    译者注:看似复杂,其实非常简单。a[] 是一个函数指针数组,a[0] = printf ; a[1] = x 。当 v/(e+1) = 0 时,调用 printf 打印数字。当 v/(e+1) = 1 时,调用 x ,跳出递归。

    方法九:

    复制代码
    #include <iostream>

    using namespace std;

    template<int N>
    void func()
    {
    func<N-1>();
    cout << N << " ";
    }

    template<>
    void func<1>()
    {
    cout << 1 << " ";
    }

    int main()
    {
    func<1000>();
    cout << endl;
    return 0;
    }
    复制代码

    译者注:和方法一有点像是吧?嗯,原理一样,只不过方法一是类模板,方法九是函数模板。

    方法十:

    复制代码
    #include <stdio.h>
    #define sign(x) (( x >> 31 ) | ( (unsigned int)( -x ) >> 31 ))

    void (*actions[3])(int);

    void Action0(int n)
    {
    printf("%d", n);
    }

    void Action1(int n)
    {
    int index;
    printf("%d ", n);
    index = sign(998-n)+1;
    actions[index](++n);
    }

    int main()
    {
    actions[0] = &Action0;
    actions[1] = 0; //Not used
    actions[2] = &Action1;

    actions[2](0);

    return 0;
    }
    复制代码

    方法十一:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>

    void f(int j)
    {
    static void (*const ft[2])(int) = { f, exit };

    printf("%d ", j);
    ft[j/1000](j + 1);
    }

    int main(int argc, char *argv[])
    {
    f(1);
    }
    复制代码

    译者注:此方法和方法八有异曲同工一秒。

    方法十二:
    C++:

    复制代码
    #include <iostream>
    using namespace std;

    static int i = 1;
    struct a
    {
    a(){cout<<i++<<endl;}
    ~a(){cout<<i++<<endl;}
    }obj[500];

    int main()
    {
    return 0;
    }
    复制代码

    C:

    复制代码
    #include <stdio.h>

    #define c1000(x) c5(c5(c5(c4(c2(x)))))
    #define c5(x) c4(x) c1(x) //or x x x x x
    #define c4(x) c2(c2(x)) //or x x x x
    #define c2(x) c1(x) c1(x) //or x x
    #define c1(x) x

    int main(int i)
    {
    c1000(printf("%d ",i++);)
    return 0;
    }
    复制代码

    一个更简单的版本:

    复制代码
    #include <stdio.h>
    #define p10(x) x x x x x x x x x x
    int main(int i)
    {
    p10(p10(p10(printf("%d ",i++);)))
    return 0;
    }
    复制代码

    方法十三:

    #include <process.h>
    int main()
    {
    system("cmd.exe /c for /l %x in (1, 1, 1000) do echo %x" );
    }

    译者注:依赖于 Windows 平台,CB不能通过编译,VS2010可正常编译和运行。

    方法十四:

    复制代码
    #include <stdio.h>

    int i=1;

    void x10( void (*f)() )
    {
    f(); f(); f(); f(); f();
    f(); f(); f(); f(); f();
    }

    void I(){printf("%i ", i++);}
    void D(){ x10( I ); }
    void C(){ x10( D ); }
    void M(){ x10( C ); }

    int main(){
    M();
    }
    复制代码

    方法十五:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    typedef void(*word)(int);

    word words[1024];

    void print(int i) {
    printf("%d ", i);
    words[i+1](i+1);
    }

    void bye(int i) {
    exit(0);
    }

    int main(int argc, char *argv[])
    {
    words[0] = print;
    words[1] = print;
    memcpy(&words[2], &words[0], sizeof(word) * 2); // 0-3
    memcpy(&words[4], &words[0], sizeof(word) * 4); // 0-7
    memcpy(&words[8], &words[0], sizeof(word) * 8); // 0-15
    memcpy(&words[16], &words[0], sizeof(word) * 16); // 0-31
    memcpy(&words[32], &words[0], sizeof(word) * 32); // 0-63
    memcpy(&words[64], &words[0], sizeof(word) * 64); // 0-127
    memcpy(&words[128], &words[0], sizeof(word) * 128); // 0-255
    memcpy(&words[256], &words[0], sizeof(word) * 256); // 0-511
    memcpy(&words[512], &words[0], sizeof(word) * 512); // 0-1023
    words[1001] = bye;
    words[1](1);
    }
    复制代码

    方法十六:

    复制代码
    #include <stdio.h>

    int printN(int n) {
    printf("%d ", n);
    return 1;
    }

    int print_range(int low, int high) {
    return ((low+1==high) && (printN(low)) ||
    (print_range(low,(low+high)/2) && print_range((low+high)/2, high)));
    }

    int main() {
    print_range(1,1001);
    }
    复制代码

    方法十七:

    复制代码
    #include<stdio.h>

    /* prints number i */
    void print1(int i) {
    printf("%d ",i);
    }

    /* prints 10 numbers starting from i */
    void print10(int i) {
    print1(i);
    print1(i+1);
    print1(i+2);
    print1(i+3);
    print1(i+4);
    print1(i+5);
    print1(i+6);
    print1(i+7);
    print1(i+8);
    print1(i+9);
    }

    /* prints 100 numbers starting from i */
    void print100(int i) {
    print10(i);
    print10(i+10);
    print10(i+20);
    print10(i+30);
    print10(i+40);
    print10(i+50);
    print10(i+60);
    print10(i+70);
    print10(i+80);
    print10(i+90);
    }

    /* prints 1000 numbers starting from i */
    void print1000(int i) {
    print100(i);
    print100(i+100);
    print100(i+200);
    print100(i+300);
    print100(i+400);
    print100(i+500);
    print100(i+600);
    print100(i+700);
    print100(i+800);
    print100(i+900);
    }


    int main() {
    print1000(1);
    return 0;
    }
    复制代码


    方法十八:

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

    译者注:亮,你们都懂的!

    方法十九:

    复制代码
    #include <stdio.h>
    #define Out(i) printf("%d ", i++);
    #define REP(N) N N N N N N N N N N
    #define Out1000(i) REP(REP(REP(Out(i))));
    int main()
    {
    int i = 1;
    Out1000(i);
    return 0;
    }
    复制代码

  • 相关阅读:
    Run Loop简介 分类: ios技术 ios相关 2015-03-11 22:21 73人阅读 评论(0) 收藏
    iOS Socket第三方开源类库 ----AsyncSocket 分类: ios相关 ios技术 2015-03-11 22:14 59人阅读 评论(0) 收藏
    CocoaPods安装和使用教程 分类: ios技术 ios相关 2015-03-11 21:53 48人阅读 评论(0) 收藏
    详解Objective-C的meta-class 分类: ios相关 ios技术 2015-03-07 15:41 51人阅读 评论(0) 收藏
    IOS即时通讯XMPP搭建openfire服务器 分类: ios技术 2015-03-07 11:30 53人阅读 评论(0) 收藏
    IOS之富文本编辑 分类: ios技术 2015-03-06 22:51 89人阅读 评论(0) 收藏
    IOS第三方数据库--FMDB 分类: ios技术 2015-03-01 09:38 57人阅读 评论(0) 收藏
    ASIHTTPRequest异步请求 分类: ios技术 2015-03-01 09:33 48人阅读 评论(0) 收藏
    python+day6 json,pickle 模块
    python_day6 log模块
  • 原文地址:https://www.cnblogs.com/noryes/p/7588294.html
Copyright © 2011-2022 走看看