Fibonacci数列的计算

msdn中在演练BackgroundWorker的时候,使用递归计算Fibonacci数列的f(n)。

        private void startAsyncButton_Click(object sender, EventArgs e)
        {
            //清空
            resultLabel.Text = String.Empty;
            //设置状态

        private int numberToCompute = 0;
        private int highestPercentageReached = 0;

            this.numericUpDown1.Enabled = true;//numericUpDown1为读入需要计算的值
            this.startAsyncButton.Enabled = false;//开始计算按钮
            this.cancelAsyncButton.Enabled = true;//取消按钮

            numberToCompute =(int) numericUpDown1.Value;
            // Reset the variable for percentage tracking.
            highestPercentageReached = 0;

            // Start the asynchronous operation.
            backgroundWorker1.RunWorkerAsync(numberToCompute);

        }

        private void cancelAsyncButton_Click(object sender, EventArgs e)
        {
            // Cancel the asynchronous operation.
            this.backgroundWorker1.CancelAsync();

            // Disable the Cancel button.
            this.cancelAsyncButton.Enabled = false;
            this.startAsyncButton.Enabled = true; ;

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the BackgroundWorker that raised this event.
            BackgroundWorker worker = sender as BackgroundWorker;
            e.Result = ComputeFibonacci((int)e.Argument, worker, e);

        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

           this.progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // First, handle the case where an exception was thrown.
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
 
                resultLabel.Text = "Canceled";
            }
            else
            {
                // Finally, handle the case where the operation
                // succeeded.
                resultLabel.Text = e.Result.ToString();
            }
            this.numericUpDown1.Enabled = true;
            startAsyncButton.Enabled = true;
            cancelAsyncButton.Enabled = false;

        }

        // This is the method that does the actual work. For this
        // example, it computes a Fibonacci number and
        // reports progress as it does its work.
        long ComputeFibonacci(int n, BackgroundWorker worker, DoWorkEventArgs e)
        {
            // The parameter n must be >= 0 and <= 91.
            // Fib(n), with n > 91, overflows a long.
            if ((n < 0) || (n > 91))
            {
                throw new ArgumentException(
                    "value must be >= 0 and <= 91", "n");
            }

            long result = 0;

            if (worker.CancellationPending)
            {
                e.Cancel = true;
            }
            else
            {
                if (n < 2)
                {
                    result = 1;
                }
                else
                {
                    result = ComputeFibonacci(n - 1, worker, e) +
                             ComputeFibonacci(n - 2, worker, e);
                }

                // Report progress as a percentage of the total task.
                int percentComplete =
                    (int)((float)n / (float)numberToCompute * 100);
                if (percentComplete > highestPercentageReached)
                {
                    highestPercentageReached = percentComplete;
                    worker.ReportProgress(percentComplete);
                }
            }

            return result;
        }

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//当然这是为了演示BackgroundWorker,其实Fibonacci数列可以如下这样计算:

        private void FibonacciForm_Load(object sender, EventArgs e)
        {
            //textBox1.Text = "斐波纳契数列(一种整数数列, 其中每数等于前面两数之和)。"
            //              + "该数列为 1、1、2、3、5、8、........"
            //               + "如果你想知道该数列的第n个数,请在下面输入n-1";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            numberToCompute = (int)numericUpDown1.Value;
            double tem = Fibonacci_2(numberToCompute);
            label1.Text = tem.ToString();
        }
        private double Fibonacci_2(int n)
        {
            if (n < 2)
                return 1;
            else
              return (Math.Pow((Math.Sqrt(5) + 1)/ 2.0, n)  - Math.Pow((1 - Math.Sqrt(5))/ 2.0, n) ) / Math.Sqrt(5);
        }

斐波那契数列是一个经典的数学问题,其定义如下: - F(0) = 0 - F(1) = 1 - 对于 n >= 2, F(n) = F(n-1) + F(n-2) 以下是使用 Python 实现的几种常见方法来计算斐波那契数列。 ### 方法一:递归实现 递归是一种直接且直观的方式来实现斐波那契数列。 ```python def fibonacci_recursive(n): if n == 0: return 0 elif n == 1: return 1 else: return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2) # 测试代码 n = 10 print(f"斐波那契数列第{n}项为: {fibonacci_recursive(n)}") ``` 上述代码中 `fibonacci_recursive` 函数通过递归调用自身来计算斐波那契数列的值。然而,这种方法的时间复杂度较高(O(2^n)),因为它会重复计算许多子问题。 --- ### 方法二:动态规划(自底向上) 为了避免重复计算,我们可以使用动态规划的方法,将每个子问题的结果存储起来以供后续使用。 ```python def fibonacci_dp(n): if n == 0: return 0 elif n == 1: return 1 dp = [0] * (n + 1) dp[1] = 1 for i in range(2, n + 1): dp[i] = dp[i - 1] + dp[i - 2] return dp[n] # 测试代码 n = 10 print(f"斐波那契数列第{n}项为: {fibonacci_dp(n)}") ``` 上述代码中 `fibonacci_dp` 函数通过一个数组 `dp` 来保存每一项的值,从而避免了重复计算。这种方法的时间复杂度为 O(n),空间复杂度也为 O(n)。 --- ### 方法三:优化的动态规划(空间优化) 在方法二的基础上,我们可以通过只保留最近的两个状态来进一步优化空间复杂度。 ```python def fibonacci_optimized(n): if n == 0: return 0 elif n == 1: return 1 prev, curr = 0, 1 for _ in range(2, n + 1): prev, curr = curr, prev + curr return curr # 测试代码 n = 10 print(f"斐波那契数列第{n}项为: {fibonacci_optimized(n)}") ``` 上述代码中 `fibonacci_optimized` 函数仅使用两个变量 `prev` 和 `curr` 来存储前两项的值,从而将空间复杂度降低到 O(1)。 --- ### 方法四:矩阵快速幂 斐波那契数列也可以通过矩阵快速幂的方法高效计算,时间复杂度为 O(log n)。 ```python def matrix_multiply(A, B): """矩阵乘法""" C = [[0, 0], [0, 0]] for i in range(2): for j in range(2): for k in range(2): C[i][j] += A[i][k] * B[k][j] return C def matrix_power(matrix, n): """矩阵快速幂""" result = [[1, 0], [0, 1]] # 单位矩阵 base = matrix while n > 0: if n % 2 == 1: result = matrix_multiply(result, base) base = matrix_multiply(base, base) n //= 2 return result def fibonacci_matrix(n): if n == 0: return 0 elif n == 1: return 1 fib_matrix = [[1, 1], [1, 0]] powered_matrix = matrix_power(fib_matrix, n - 1) return powered_matrix[0][0] # 测试代码 n = 10 print(f"斐波那契数列第{n}项为: {fibonacci_matrix(n)}") ``` 上述代码中 `matrix_power` 函数实现了矩阵的快速幂运算,`fibonacci_matrix` 函数利用矩阵快速幂的性质来高效计算斐波那契数列的第 n 项。 --- ### 解释 1. **递归方法** 直观但效率低,适合小规模计算。 2. **动态规划方法** 提高了效率,但需要额外的空间。 3. **优化的动态规划** 进一步减少了空间开销。 4. **矩阵快速幂方法** 是最高效的算法之一,尤其适用于大规模计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值