Chinaunix首页 | 论坛 | 博客
  • 博客访问: 501824
  • 博文数量: 137
  • 博客积分: 3874
  • 博客等级: 中校
  • 技术积分: 1475
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-05 10:50
文章分类

全部博文(137)

文章存档

2011年(37)

2010年(100)

分类: C/C++

2011-01-08 20:55:22

有这样一个面试题——请把从1到1000的数打印出来,但你不能使用任何的循环语句或是条件语句。更不能写1000个printf或是cout用C/C++语言

我相信,大多数人一开始你可能想到的是递归算法:

  1. void f(int n){
  2.     printf("%d\n",n);
  3.     (1000-n) ? f(n+1) : exit(0) ;
  4. }
  5. int main(){
  6.     f(1);
  7. }

当然,题目中说了不能使用条件语句,所以,上面那种解法的不符合题意的,因为还是变向地使用了条件表达式。不过,我们可以用别的方法来让这个递归终止,比如:

除以零,当程序crash,呵呵

  1. void f(int n){
        printf("%d\n",n);
        n/(1000-n);
        f(n+1);
    }

还有这样退出递归的:

  1. void yesprint(int i);
  2. void noprint(int i);
  3.  
  4. typedef void(*fnPtr)(int);
  5. fnPtr dispatch[] = { yesprint, noprint };
  6.  
  7. void yesprint(int i) {
  8.     printf("%d\n", i);
  9.     dispatch[i / 1000](i + 1);
  10. }
  11.  
  12. void noprint(int i) { /* do nothing. */ }
  13.  
  14. int main() {
  15.       yesprint(1);
  16. }

还有下面这些各种各样的解法:

  1. #include<stdio.h>
  2.  
  3. /* prints number i */
  4. void print1(int i) {
  5.     printf("%d\n",i);
  6. }
  7.  
  8. /* prints 10 numbers starting from i */
  9. void print10(int i) {
  10.     print1(i);
  11.     print1(i+1);
  12.     print1(i+2);
  13.     print1(i+3);
  14.     print1(i+4);
  15.     print1(i+5);
  16.     print1(i+6);
  17.     print1(i+7);
  18.     print1(i+8);
  19.     print1(i+9);
  20. }
  21.  
  22. /* prints 100 numbers starting from i */
  23. void print100(int i) {
  24.     print10(i);
  25.     print10(i+10);
  26.     print10(i+20);
  27.     print10(i+30);
  28.     print10(i+40);
  29.     print10(i+50);
  30.     print10(i+60);
  31.     print10(i+70);
  32.     print10(i+80);
  33.     print10(i+90);
  34. }
  35.  
  36. /* prints 1000 numbers starting from i */
  37. void print1000(int i) {
  38.     print100(i);
  39.     print100(i+100);
  40.     print100(i+200);
  41.     print100(i+300);
  42.     print100(i+400);
  43.     print100(i+500);
  44.     print100(i+600);
  45.     print100(i+700);
  46.     print100(i+800);
  47.     print100(i+900);
  48. }
  49.  
  50. int main() {
  51.         print1000(1);
  52.         return 0;
  53. }

不过,print用得多了一些。我们可以用宏嘛。

  1. #include<stdio.h>
  2. #define Out(i) printf("%d\n", i++);
  3. #define REP(N) N N N N N N N N N N
  4. #define Out1000(i) REP(REP(REP(Out(i))));
  5. void main()
  6. {
  7.     int i = 1;
  8.     Out1000(i);

不过,我们应该使用C++的一些特性,比如:

使用构造函数

  1. class Printer
  2. {
  3. public:
  4.     Printer() { static unsigned i=1; cout << i++ << endl;; }
  5.  
  6. };
  7.  
  8. int main()
  9. {
  10.     Printer p[1000];
  11. }

或是更为NB的Template:

  1. template<int N>
  2. struct NumberGeneration{
  3.     static void out(std::ostream& os)
  4.     {
  5.         NumberGeneration<N-1>::out(os);
  6.         os << N << std::endl;
  7.     }
  8. };
  9.  
  10. template<>
  11. struct NumberGeneration<1>{
  12.     static void out(std::ostream& os)
  13.     {
  14.         os << 1 << std::endl;
  15.     }
  16. };
  17.  
  18. int main(){
  19.     NumberGeneration<1000>::out(std::cout);
  20. }

最后来个BT一点的:

#include #include
void main(int j) {
    printf("%d\n", j);
    (main + (exit - main)*(j/1000))(j+1);
}

分析一下这个BT函数,其实还好,比较好理解,关键是(main + (exit - main)*(j/1000))(j+1)这个地方,
我们知道程序里面main 或者exit或者其他的函数,都是一个别名,指向函数实际的内存地址。
(f)(arglist)就能调用带参数列表arglist的函数f了。
在上面,main + (exit - main)*(j/1000)其实在j<1000时,为main+(exit-main)*0=main,调用main(j+1)。
当j=1000时,调用的是main + (exit-main)*1 = exit这个函数,然后就退出了。

原来main也可以调用自己,写了一个测试小程序^_^ 
  1. #include <stdlib.h>
  2. #include <stdio.h>

  3. typedef void(*p2Foo)(int) ;

  4. void prt(int a)
  5. {
  6.   printf("int prt ^_^ %d\n",a);
  7. }

  8. p2Foo p2f = prt;

  9. void main(int argc )
  10. {
  11.   printf("%d\n",argc);
  12.   //printf("main %d p2f %d next %d and arg is %d \n", main, p2f, main+(p2f - main)*(argc/100),argc+1);
  13.   (main+(p2f - main)*(argc/100))(argc+1);
  14.   printf("ends with argc %d \n", argc);
  15. }

参考:来源:
Insert mode
阅读(1772) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~