『代码』··By/蜜汁炒酸奶

k 阶斐波那契序列的第 m 项值的函数算法—C语言

/***************************************************
作业要求:
		求 k 阶斐波那契序列的第 m 项值的函数算法

完成日期:
		2013年9月3日
***************************************************/
#include <stdio.h>

// 函数原型
int fibnocci_1(int m, int k);
int fibnocci_2(int m, int k);
int fibnocci_3(int m, int k);

// main函数
int main(void)
{
	// 求3阶fibnocci数列第8项的值
	// 0 0 1 1 2 4 7 13 24 ……
	printf("%dn", fibnocci_1(8, 3));
	printf("%dn", fibnocci_2(8, 3));
	printf("%dn", fibnocci_3(8, 3));

	return 0;
}

/****************************************************
函数功能:
		求k阶fibnocci数列的第m项值
算法思想:
		(1) 根据m和k的值,先返回特殊情况下的值;
		(2) 首先初始化前k项值;
		(3) 按照公式求第k+1项至第m项的值。
函数参数:
		int		m		待求fibnocci数列项数
		int		k		fibnocci数列的阶数
返回值:
		返回k阶fibnocci数列第m项的值
时间复杂度:
		O(m * k):双重循环(外层为m-k,内层为k)
空间复杂度:
		O(m):	开辟的辅助存储空间总共有m+3个(f、i、j、result)
*****************************************************/
int fibnocci_1(int m, int k)
{
	int i, j, result;
	int *f;				// 辅助数组空间
	// 特殊情况
	if (m < k-1)
	{
		return 0;
	}
	else if (m == k-1 || m == k)
	{
		return 1;
	}

	// 一般情况

	// 动态内存分配辅助空间
	f = (int *) malloc(sizeof(int) * (m+1));

	// 初始化前k项的值
	for (i = 0; i < k-1; ++i)
	{
		f[i] = 0;
	}
	f[k-1] = f[k] = 1;

	// 求第m项值
	for (i = k+1; i <= m; ++i)
	{
		f[i] = 0;
		for (j = 1; j <= k; ++j)
		{
			f[i] += f[i - j];
		}
	}
	result = f[m];

	// 释放辅助空间
	free(f);

	return result;
}

/****************************************************
函数功能:
		求k阶fibnocci数列的第m项值
算法思想:
		(1) 根据m和k的值,先返回特殊情况下的值;
		(2) 首先初始化前k项值;
		(3) 按照公式求第k+1项至第m项的值(借助数学运算简化求解)。
函数参数:
		int		m		待求fibnocci数列项数
		int		k		fibnocci数列的阶数
返回值:
		返回k阶fibnocci数列第m项的值
时间复杂度:
		O(m):	计算第m项时,借助数学公式取消内层循环
空间复杂度:
		O(m):	开辟的辅助存储空间总共有m+3个(f、i、j、result)
*****************************************************/
int fibnocci_2(int m, int k)
{
	int i, j, result;
	int *f;				// 辅助数组空间
	// 特殊情况
	if (m < k-1)
	{
		return 0;
	}
	else if (m == k-1 || m == k)
	{
		return 1;
	}

	// 一般情况

	// 动态内存分配辅助空间
	f = (int *) malloc(sizeof(int) * (m+1));

	// 初始化前k项的值
	for (i = 0; i < k-1; ++i)
	{
		f[i] = 0;
	}
	f[k-1] = f[k] = 1;

	// 求第m项值
	for (i = k+1; i <= m; ++i)
	{
		// 按照数学公式计算
		f[i] = 2 * f[i - 1] - f[i - k - 1];
	}
	result = f[m];

	// 释放辅助空间
	free(f);

	return result;
}

/****************************************************
函数功能:
		求k阶fibnocci数列的第m项值
算法思想:
		递归求解。
函数参数:
		int		m		待求fibnocci数列项数
		int		k		fibnocci数列的阶数
返回值:
		返回k阶fibnocci数列第m项的值
时间复杂度:
		O(k^m):	由递归式:f(m) = k * f(m-1),
		则f(m) = k * k * f(m-2),以此类推可得,
		f(m) = k^m
空间复杂度:
		O(m * k):	每一次递归调用过程中需要求得其前k项的值,
		共需递归调用m次,故总共的辅助空间约为 m * k个。
*****************************************************/
int fibnocci_3(int m, int k)
{
	int i, result = 0;
	if (m < k - 1)
	{
		return 0;
	}
	else if (m == k - 1 || m == k)
	{
		return 1;
	}
	else
	{
		for (i = 1; i <= k; ++i)
		{
			result += fibnocci_3(m - i, k);
		}
		return result;
	}
}
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

预览
Loading comments...
2 条评论
  • W

    :cool: 文章很专业哦,俺看不懂了哈。路过,照顶。

example
预览