您的位置:首页 > 编程语言 > Go语言

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

2014-05-09 14:29 447 查看
这是quora上的一篇帖子,很有意思,整理出来,由此见识了编程语言的强大。

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

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

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

1、

#include <iostream>
int main()
{
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";
return 0;
}


2、

#include <cstdio>

int main() {
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");
}


3、

#include <iostream>
using namespace std;
int main()
{
cout<<"1"<<endl;
cout<<"2"<<endl;
cout<<"3"<<endl;
cout<<"4"<<endl;
cout<<"5"<<endl;
cout<<"6"<<endl;
cout<<"7"<<endl;
cout<<"8"<<endl;
cout<<"9"<<endl;
cout<<"10"<<endl;
cout<<"11"<<endl;

(contd...)

cout<<"91"<<endl;
cout<<"92"<<endl;
cout<<"93"<<endl;
cout<<"94"<<endl;
cout<<"95"<<endl;
cout<<"96"<<endl;
cout<<"97"<<endl;
cout<<"98"<<endl;
cout<<"99"<<endl;
cout<<"100"<<endl;

return 0;

}


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

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

1、

#include <stdio.h>

template<int N>
struct X : X<N-1> {
X() { printf("%d\n", N); }
};

template<>
struct X<0> {};

int main() {
X<100> x;
return 0;
}


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

2、

#include <stdio.h>

struct X {
static int i;

X() { ++i; printf("%d\n", i); }
};

int X::i = 0;

int main() {
X arr[100];
return 0;
}


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

3、

class Printupto100
{
public:
static int i;
Printupto100()
{
i++;
cout<<i<<endl;
}
};

int Printupto100::i = 0;

int main()
{
int N = 100;
Printupto100 obj
;
return 0;
}


同上思路

4、

int g_index = 1;
struct print
{
print()
{
cout << g_index++;
}
};
.........

new print[100];


继续同上

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

1、

include <stdlib.h>

int main() {
/* Cross your fingers and hope seq exists! */
return system("seq 1 100");
}


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

2、

#include <stdlib.h>

int main() {
system ("perl -e 'print 1..100'");
}


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

3、

#include <iostream>
#include <stdlib.h>

int num;
void(**rptr)();

void foo() {
if(num >= 100) exit(0);
std::cout << ++num << std::endl;
*rptr++ = foo;
}

int main() {
rptr = (void(**)())alloca(sizeof(*rptr) * 200) - 1;
foo();
return 0;
}


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

4、

#include <iostream>
#include <numeric>
#include <iterator>
#include <array>

int main() {
std::array<int, 100> arr;

std::iota(begin(arr), end(arr), 1);

std::copy(begin(arr), end(arr), std::ostream_iterator<int>(std::cout, "\n"));
}


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

5、

#import <iostream>
using namespace std;

class Incrementor
{
public:
int value;
int operator()()
{
return ++value;
}
};

int main()
{
generate_n(ostream_iterator<int>(cout, "\n"), 100, Incrementor());
}


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

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

#include <iostream>
#include <stdlib.h>

int main() {
int x = 0;
x |= !fork() << 0;
x |= !fork() << 1;
x |= !fork() << 2;
x |= !fork() << 3;
x |= !fork() << 4;
x |= !fork() << 5;
x |= !fork() << 6;
if(1 <= x && x <= 100) std::cout << x << std::endl;
return 0;
}


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

2、

#include <stdio.h>

#define F4 "%d\n%d\n%d\n%d\n"
#define F20 F4 F4 F4 F4 F4
#define F100 F20 F20 F20 F20 F20

#define X4(y) , y, y + 1, y + 2, y + 3
#define X20(y) X4(y) X4(y + 4) X4(y + 8) X4(y + 12) X4(y + 16)
#define X100(y) X20(y) X20(y + 20) X20(y + 40) X20(y + 60) X20(y + 80)

int main() {
printf(F100 X100(1));
return 0;
}


这个宏,不评论

3、

#include <stdio.h>

#define STEP1 step();
#define STEP2 STEP1 STEP1
#define STEP4 STEP2 STEP2
#define STEP8 STEP4 STEP4
#define STEP16 STEP8 STEP8
#define STEP32 STEP16 STEP16
#define STEP64 STEP32 STEP32
#define STEP128 STEP64 STEP64

int n = 0;

int step()
{
if (++n <= 100)
printf("%d\n", n);
}

int main()
{
STEP128;
}


继续不解释

4、

#include <iostream>

using namespace std;

#define   SEQ1(K)  K
#define   SEQ2(K)  SEQ1(K) << endl <<  SEQ1(K +  1)
#define   SEQ4(K)  SEQ2(K) << endl <<  SEQ2(K +  2)
#define   SEQ8(K)  SEQ4(K) << endl <<  SEQ4(K +  4)
#define  SEQ16(K)  SEQ8(K) << endl <<  SEQ8(K +  8)
#define  SEQ32(K) SEQ16(K) << endl << SEQ16(K + 16)
#define  SEQ64(K) SEQ32(K) << endl << SEQ32(K + 32)

int main(int, char **) {
cout << SEQ4 ( 1) << endl;
cout << SEQ32( 5) << endl;
cout << SEQ64(37) << endl;
}


闲得蛋疼啊!

5、

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/types.h>
#include <signal.h>

int i = 0;
void sig_alarm_handler(int signal) {
++i;
printf("%d\n", i);
if(i < 100)
alarm(1);
else
exit(0);
}

int main() {
signal(SIGALRM, sig_alarm_handler);
alarm(1);
int x;
scanf(" %d",&x);
return 0;
}


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

6、

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

int mypid;

void signal_handler(int signal, siginfo_t* siginfo, void* extra) {
printf("%d\n", siginfo->si_int);
sigval_t signal_value;
memcpy(&signal_value, &siginfo->si_value, sizeof(signal_value));
++signal_value.sival_int;
if(signal_value.sival_int <= 100)
sigqueue(mypid, SIGUSR1, signal_value);
else
exit(0);

}

int main() {
mypid = getpid();

struct sigaction sa;
bzero(&sa, sizeof(sa));
sa.sa_sigaction = signal_handler;
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART;

sigaction(SIGUSR1, &sa, NULL);

sigval_t signal_value;
signal_value.sival_int = 1;
sigqueue(mypid, SIGUSR1, signal_value);
sleep(1000);
return 0;
}


同上吧

7、

#include <stdlib.h>
#include <stdio.h>

int main() {
FILE* fd = fopen("data.txt", "r");
char buf[10000];
size_t n = fread(buf, sizeof(char), 10000, fd);
fwrite(buf, sizeof(char), n, stdout);
fflush(stdout);
fclose(fd);
return 0;
}


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

8、

#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
int fd = open("data.txt", O_RDONLY);
struct stat stat_data;
fstat(fd, &stat_data);
off_t file_size = stat_data.st_size;

// Memory map the file
void* baseaddr = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
// Copy the memory mapped region to stdout
fwrite((char*)baseaddr, sizeof(char), file_size, stdout);
fflush(stdout);

// Unmap the memory mapped region
munmap(baseaddr, file_size);

// Close the file
close(fd);
return 0;
}


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

9、

#include <iostream>
using namespace std;

int main(void)
{
int i = 1;
asm("begin_loop:");
if (i <= 100)
{
cout << i << endl;
i++;
asm("jmp begin_loop");
}
return 0;
}


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

10、 

public class Test2 {

static class MyThread implements Runnable {
int i;
int MaxLimit;
MyThread(int pI,int pMaxLimit){
this.i=pI;
this.MaxLimit=pMaxLimit;
}
@Override
public void run() {
print();
}

void print() {
try {
System.out.println(i * ((MaxLimit + 1 - i) / (MaxLimit + 1 - i)));
new Thread(new Test2.MyThread(this.i+1,this.MaxLimit)).start();
} catch (Exception e) {
}
}
}

public static void main(String[] args) {

new Thread(new Test2.MyThread(1,100)).start();
}

}


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

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

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

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

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

转载请注明出处:/article/7121272.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: