不用循环、goto、递归打印1至100的各路写法


这是quora上的一篇帖子,很有意思,整理出来,由此见识了编程语言的强大。

原帖地址:http://www.quora.com/Algorithms/How-can-I-print-1-to-100-in-C++-without-a-loop-GOTO-or-recursion

不怕英文的可以去看原帖,(-_-)

一、首先来见识下二逼程序员的写法:

1、

1 #include <iostream>
2 int main()
3 {
4     std::cout << "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40\n41\n42\n43\n44\n45\n46\n47\n48\n49\n50\n51\n52\n53\n54\n55\n56\n57\n58\n59\n60\n61\n62\n63\n64\n65\n66\n67\n68\n69\n70\n71\n72\n73\n74\n75\n76\n77\n78\n79\n80\n81\n82\n83\n84\n85\n86\n87\n88\n89\n90\n91\n92\n93\n94\n95\n96\n97\n98\n99\n100\n";
5     return 0;
6 }

2、

1 #include <cstdio>
2 
3 int main() {
4     printf("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100");
5 }

3、

 1 #include <iostream>
 2 using namespace std;
 3 int main() 
 4 {
 5     cout<<"1"<<endl;
 6     cout<<"2"<<endl;
 7     cout<<"3"<<endl;
 8     cout<<"4"<<endl;
 9     cout<<"5"<<endl;
10     cout<<"6"<<endl;
11     cout<<"7"<<endl;
12     cout<<"8"<<endl;
13     cout<<"9"<<endl;
14     cout<<"10"<<endl;
15     cout<<"11"<<endl;
16 
17     (contd...)
18 
19     cout<<"91"<<endl;
20     cout<<"92"<<endl;
21     cout<<"93"<<endl;
22     cout<<"94"<<endl;
23     cout<<"95"<<endl;
24     cout<<"96"<<endl;
25     cout<<"97"<<endl;
26     cout<<"98"<<endl;
27     cout<<"99"<<endl;
28     cout<<"100"<<endl;
29 
30     return 0;
31 
32 }

嗯,大同小异,符合dang的要求,没有循环,没有递归,没有goto语句。

二、我们来看看普通程序员的思路

1、

 1 #include <stdio.h>
 2 
 3 template<int N>
 4 struct X : X<N-1> {
 5     X() { printf("%d\n", N); }
 6 };
 7 
 8 template<>
 9 struct X<0> {};
10 
11 int main() {
12     X<100> x;
13     return 0;
14 }

这里使用了模板的特化,对C++的模板比较了解

2、

 1 #include <stdio.h>
 2 
 3 struct X {
 4     static int i;
 5 
 6     X() { ++i; printf("%d\n", i); }
 7 };
 8 
 9 int X::i = 0;
10 
11 int main() {
12     X arr[100];
13     return 0;
14 }

这里使用了静态对象来实现递增效果

3、

 1 class Printupto100
 2 {
 3     public:
 4     static int i;
 5     Printupto100()
 6     { 
 7          i++;
 8          cout<<i<<endl;  
 9      }
10 };
11  
12 int Printupto100::i = 0;
13  
14 int main()
15 {
16     int N = 100;
17     Printupto100 obj[N];
18     return 0;
19 }

同上思路

4、

 1 int g_index = 1;
 2 struct print
 3 {
 4 print()
 5 {
 6 cout << g_index++;
 7 }
 8 };
 9 .........
10 
11 new print[100];

继续同上

三、好了,接下来见识一下文艺程序员的写法

1、

1 include <stdlib.h>
2 
3 int main() {
4   /* Cross your fingers and hope seq exists! */
5   return system("seq 1 100");
6 }

这个有点意思,笔者之前也没见过这么风骚的写法,赞一个

2、

1 #include <stdlib.h>
2 
3 int main() {
4     system ("perl -e 'print 1..100'");
5 }

这个作弊啊,用了perl.....

3、

 1 #include <iostream>
 2 #include <stdlib.h>
 3 
 4 int num;
 5 void(**rptr)();
 6 
 7 void foo() {
 8   if(num >= 100) exit(0);
 9   std::cout << ++num << std::endl;
10   *rptr++ = foo;
11 }
12 
13 int main() {
14   rptr = (void(**)())alloca(sizeof(*rptr) * 200) - 1;
15   foo();
16   return 0;
17 }

这个和上面的代码出自同一个作者。原作者注释:我的系统可以运行,虽然不保证结果.......    -_-

4、

 1 #include <iostream>
 2 #include <numeric>
 3 #include <iterator>
 4 #include <array>
 5 
 6 int main() {
 7   std::array<int, 100> arr;
 8 
 9   std::iota(begin(arr), end(arr), 1);
10 
11   std::copy(begin(arr), end(arr), std::ostream_iterator<int>(std::cout, "\n"));
12 }

这个写法也极为风骚,好吧,笔者对ostream_iterator完全黑线,回头再看看标准库,array也用得很好,自叹不如啊

5、

 1 #import <iostream>
 2     using namespace std;
 3 
 4     class Incrementor
 5     {
 6     public:
 7         int value;
 8         int operator()()
 9         {
10             return ++value;
11         }
12     };
13 
14     int main()
15     {
16         generate_n(ostream_iterator<int>(cout, "\n"), 100, Incrementor());
17     }

再来一个,都要哭了→_→

四、火大,现在见证普通人和牛人的区别的时候来了,看看下面的代码,我只能说,精妙!
1、

 1 #include <iostream>
 2 #include <stdlib.h>
 3 
 4 int main() {
 5   int x = 0;
 6   x |= !fork() << 0;
 7   x |= !fork() << 1;
 8   x |= !fork() << 2;
 9   x |= !fork() << 3;
10   x |= !fork() << 4;
11   x |= !fork() << 5;
12   x |= !fork() << 6;
13   if(1 <= x && x <= 100) std::cout << x << std::endl;
14   return 0;
15 }

这尼玛都fork上了,高端大气上档次!

2、

 1 #include <stdio.h>
 2 
 3 #define F4 "%d\n%d\n%d\n%d\n"
 4 #define F20 F4 F4 F4 F4 F4
 5 #define F100 F20 F20 F20 F20 F20
 6 
 7 #define X4(y) , y, y + 1, y + 2, y + 3
 8 #define X20(y) X4(y) X4(y + 4) X4(y + 8) X4(y + 12) X4(y + 16)
 9 #define X100(y) X20(y) X20(y + 20) X20(y + 40) X20(y + 60) X20(y + 80)
10 
11 int main() {
12   printf(F100 X100(1));
13   return 0;
14 }

这个宏,不评论

3、

 1 #include <stdio.h>
 2 
 3 #define STEP1 step();
 4 #define STEP2 STEP1 STEP1
 5 #define STEP4 STEP2 STEP2
 6 #define STEP8 STEP4 STEP4
 7 #define STEP16 STEP8 STEP8
 8 #define STEP32 STEP16 STEP16
 9 #define STEP64 STEP32 STEP32
10 #define STEP128 STEP64 STEP64
11 
12 int n = 0;
13 
14 int step()
15 {
16   if (++n <= 100)
17     printf("%d\n", n);
18 }
19 
20 int main()
21 {
22   STEP128;
23 }

继续不解释

4、

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 #define   SEQ1(K)  K
 6 #define   SEQ2(K)  SEQ1(K) << endl <<  SEQ1(K +  1)
 7 #define   SEQ4(K)  SEQ2(K) << endl <<  SEQ2(K +  2)
 8 #define   SEQ8(K)  SEQ4(K) << endl <<  SEQ4(K +  4)
 9 #define  SEQ16(K)  SEQ8(K) << endl <<  SEQ8(K +  8)
10 #define  SEQ32(K) SEQ16(K) << endl << SEQ16(K + 16)
11 #define  SEQ64(K) SEQ32(K) << endl << SEQ32(K + 32)
12 
13 int main(int, char **) {
14   cout << SEQ4 ( 1) << endl;
15   cout << SEQ32( 5) << endl;
16   cout << SEQ64(37) << endl;
17 }

 闲得蛋疼啊!

5、

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #include <unistd.h>
 5 #include <sys/types.h>
 6 #include <signal.h>
 7 
 8 int i = 0;
 9 void sig_alarm_handler(int signal) {
10     ++i;
11     printf("%d\n", i);
12     if(i < 100)
13         alarm(1);
14     else
15         exit(0);
16 }
17 
18 int main() {
19     signal(SIGALRM, sig_alarm_handler);
20     alarm(1);
21     int x;
22     scanf(" %d",&x);
23     return 0;
24 }

信号量都用上了,用不用这么大动干戈!!!

6、

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <assert.h>
 4 #include <string.h>
 5 
 6 #include <sys/types.h>
 7 #include <unistd.h>
 8 #include <signal.h>
 9 
10 int mypid;
11 
12 void signal_handler(int signal, siginfo_t* siginfo, void* extra) {
13     printf("%d\n", siginfo->si_int);
14     sigval_t signal_value;
15     memcpy(&signal_value, &siginfo->si_value, sizeof(signal_value));
16     ++signal_value.sival_int;
17     if(signal_value.sival_int <= 100)
18         sigqueue(mypid, SIGUSR1, signal_value);
19     else
20         exit(0);
21 
22 }
23 
24 int main() {
25     mypid = getpid();
26 
27     struct sigaction sa;
28     bzero(&sa, sizeof(sa));
29     sa.sa_sigaction = signal_handler;
30     sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;
31 
32     sigaction(SIGUSR1, &sa, NULL);
33 
34     sigval_t signal_value;
35     signal_value.sival_int = 1;
36     sigqueue(mypid, SIGUSR1, signal_value);
37     sleep(1000);
38     return 0;
39 }

同上吧

7、

 1 #include <stdlib.h>
 2 #include <stdio.h>
 3 
 4 int main() {
 5     FILE* fd = fopen("data.txt", "r");
 6     char buf[10000];
 7     size_t n = fread(buf, sizeof(char), 10000, fd);
 8     fwrite(buf, sizeof(char), n, stdout);
 9     fflush(stdout);
10     fclose(fd);
11     return 0;
12 }

额,其实,读读文件,其实不能算作这一类,斟酌了很久,想法不错!

8、

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #include <sys/types.h>
 5 #include <sys/stat.h>
 6 #include <sys/mman.h>
 7 #include <fcntl.h>
 8 #include <unistd.h>
 9 
10 int main() {
11     int fd = open("data.txt", O_RDONLY);
12     struct stat stat_data;
13     fstat(fd, &stat_data);
14     off_t file_size = stat_data.st_size;
15 
16     // Memory map the file
17     void* baseaddr = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
18     // Copy the memory mapped region to stdout
19     fwrite((char*)baseaddr, sizeof(char), file_size, stdout);
20     fflush(stdout);
21 
22     // Unmap the memory mapped region
23     munmap(baseaddr, file_size);
24 
25     // Close the file
26     close(fd);
27     return 0;
28 }

内存映射了,尼玛,最讨厌内存了,一不小心就死翘翘!

9、

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(void)
 5 {
 6   int i = 1;
 7   asm("begin_loop:");
 8   if (i <= 100)
 9   {
10     cout << i << endl;
11     i++;
12     asm("jmp begin_loop");
13   }
14   return 0;
15 }

汇编都用上了,欺负俺,而且作弊,这不就是goto吗?哼!

10、 

 1 public class Test2 {
 2 
 3      static class MyThread implements Runnable {
 4                int i;
 5                int MaxLimit;
 6         MyThread(int pI,int pMaxLimit){
 7             this.i=pI;
 8             this.MaxLimit=pMaxLimit;
 9         }
10         @Override
11         public void run() {
12             print();
13         }
14 
15         void print() {
16             try {
17                 System.out.println(i * ((MaxLimit + 1 - i) / (MaxLimit + 1 - i)));
18                 new Thread(new Test2.MyThread(this.i+1,this.MaxLimit)).start();
19             } catch (Exception e) {
20             }
21         }
22     }
23 
24     public static void main(String[] args) {
25 
26         new Thread(new Test2.MyThread(1,100)).start();
27     }
28 
29 }

尼玛还玩上线程了,跟上面的fork遥相呼应啊!

========================================================================================

好吧,完了,一个小小的程序,可能99%的情况下,大家会用循环去处理。看了这篇博文,会不会觉得编程世界五彩纷呈?

如果你还有更好的想法,可以提出来,不限语言,最好有新思路的!不接受比如bash啥的交互式脚本语言的普通写法,因为俺也会-_-

/*有些代码笔者也没去验证,如果有兴趣,请自行验证*/

转载请注明出处:http://www.cnblogs.com/yuanzz/p/3718840.html

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM