您的位置:首页 > 其它

实现1+2+3...+n,要求不能使用乘除法、循环、条件判断、选择相关的关键字(for、while、if、else、switch、case)。

2017-07-15 13:59 966 查看
解法1:利用递归(&&的短路特性)

&&的短路特性:即A&&B中,加入A为假,那么B就不会被运算,因此我们只要将递归放在B中,而将终止条件放在A中即可解决该问题。。。

1 /**************************************
2 *文件说明:recursion.cpp
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 09时54分25秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include<stdio.h>
9
10 int add(int n,int &sum)
11 {
12     n && add(n-1,sum);
13     return (sum += n);
14 }
15
16 int main()
17 {
18     int sum = 0;
19     int n = 0;
20     int ret = 0;
21
22     printf("please enter last number:");
23     scanf("%d",&n);
24     ret = add(n,sum);
25     printf("1+2+...+%d = %d\n",n,ret);
26
27     return 0;
28 }


运行结果:



注意:C语言不能传引用,所以此处用g++编译.cpp文件来测验,如果不想用引用,指针也可实现。

用指针代替引用:

1 /**************************************
2 *文件说明:recursion.c
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 09时59分25秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include<stdio.h>
9
10 int add(int n,int *sum)
11 {
12     n && add(n-1,sum);
13     return (*sum += n);
14 }
15
16 int main()
17 {
18     int sum = 0;
19     int n = 0;
20     int ret = 0;
21
22     printf("please enter last number:");
23     scanf("%d",&n);
24     ret = add(n,&sum);
25     printf("1+2+...+%d = %d\n",n,ret);
26
27     return 0;
28 }


运行结果:



解法1:利用递归(&&的短路特性)的时间复杂度:O(n)

解法2:利用构造函数和静态数据成员

1 /**************************************
2 *文件说明:construct.cpp
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 10时58分32秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include<iostream>
9 using namespace std;
10
11 class Add
12 {
13 public:
14     Add()
15     {
16         ++_n;
17         _sum += _n;
18     }
19     static void Reset()
20     {
21         _sum = 0;
22         _n = 0;
23     }
24     static int Get()
25     {
26         return _sum;
27     }
28 private:
29     static int _n;
30     static int _sum;
31 };
32
33 int Add::_n = 0;
34 int Add::_sum = 0;
35
36 int main()
37 {
38     int n = 0;
39     cout<<"please enter last number:";
40     cin>>n;
41
42     Add::Reset();
43     Add* a = new Add
;
44     delete []a;
45     a = NULL;
46
47     cout<<"1+2+...+n = "<<Add::Get()<<endl;
48     return 0;
49 }


运行结果:



解法2:利用构造函数和静态数据成员的时间复杂度O(1)

解法3:利用函数指针

1 /**************************************
2 *文件说明:funpoint.cpp
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 13时16分59秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include<iostream>
9 using namespace std;
10
11 typedef int (*fun)(int);
12
13 int fun1(int num)
14 {
15     return 0;
16 }
17
18 int fun2(int num)
19 {
20     fun f[2] = {fun1,fun2};
21     return num + f[!!num](num-1);
22 }
23
24 int main()
25 {
26     int n = 0;
27     cout<<"please enter last number:";
28     cin>>n;
29     printf("1+2+...+%d = %d\n",n,fun2(n));
30     return 0;
31 }


其中f[!!i]是限定函数指针f的下标为只能为0和1,默认所有非0值结果都为真,以此来保证不越界访问(下同)。

运行结果:



解法3:利用函数指针的时间复杂度为O(n)

解法4:利用虚函数

1 /**************************************
2 *文件说明:virtualfun.cpp
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 13时33分57秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include <iostream>
9 using namespace std;
10
11 class A;
12 A* Array[2];
13
14 class A
15 {
16 public:
17     virtual int Sum(int n)
18     {
19         return 0;
20     }
21 };
22
23 class B:public A
24 {
25 public:
26     virtual int Sum(int n)
27     {
28         return Array[!!n]->Sum(n-1)+n;
29     }
30 };
31
32 int Sum(int n)
33 {
34     A a;
35     B b;
36     Array[0]=&a;
37     Array[1]=&b;
38
39     int value=Array[1]->Sum(n);
40     return value;
41 }
42
43 int main()
44 {
45     int n = 0;
46     cout<<"please enter last number:";
47     cin>>n;
48     cout<<"1+2+...+"<<n<<" = "<<Sum(n)<<endl;
49     return 0;
50 }


运行结果:



解法4:利用虚函数的时间复杂度为O(n)

解法5:利用模板和关键字inline

1 /**************************************
2 *文件说明:template.cpp
3 *作者:段晓雪
4 *创建时间:2017年07月15日 星期六 11时44分52秒
5 *开发环境:Kali Linux/g++ v6.3.0
6 ****************************************/
7
8 #include<iostream>
9 using namespace std;
10
11 template<int n> inline int Sum(int m)
12 {
13     return Sum<n-1>(m-1)+m;
14 }
15
16 template<> inline int Sum<1>(int m)
17 {
18     return 1;
19 }
20
21 template<> inline int Sum<0>(int m)
22 {
23     return 0;
24 }
25
26 int main()
27 {
28     int sum = Sum<100>(100);
29     cout<<sum<<endl;
30     return 0;
31 }


运行结果:



解法5:利用模板和关键字inline的时间复杂度O(n)

总结:

解法1:利用递归(&&的短路特性)—-O(n)

解法2:利用构造函数和静态数据成员—-O(1)

解法3:利用函数指针—-O(n)

解法4:利用虚函数—-O(n)

解法5:利用模板和关键字inline—-O(n)

分析:这题本来很简单,但是不能用循环和条件判断语句。由于理论上所有的循环都可以转化为递归,所以我们考虑用递归代替循环。可是用递归的话,递归怎么终止呢?这就得在return语句中做文章了,其中解法1、3、4、5都是利用了隐形的递归实现的,只是借助了不同的方式你来进行返回。

思路:

把循环化为递归。

乘法改为递归实现的累加。

递归的终止靠return语句做文章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  递归
相关文章推荐