第二章 算法时间复杂度

做~自己de王妃 提交于 2020-02-19 23:23:36

一、主定理

在这里插入图片描述

1、 主要是计算 n_log_b_a 。求出来之后和后面的Fn进行比较,然后按照规则些出结果就行。
2、一句话解释:这两个值哪一个大就取谁;想等的话先看Fn里面log的次数,最终的结果在log的基础之上+1就是最终结果log的次数。例题如右下角
3、要注意的一点就是:保证T(n)的形式要和定理里面的一样,一个大问题拆解成为几个相等的小问题。

在这里插入图片描述
在这里插入图片描述

1、例题如上。
2、N!是阶数最高的,属于NP难问题。复杂度是最大的。
3、n的n次方乘以log n。

  • Fib数列递推公式的证明(斐波那契数列)

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……
斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式::F(n)=F(n-1)+F(n-2)

显然这是一个线性递推数列。

先回顾一下常微分方程:fib数列。假设y=e的lλx次方,解出y。
在这里插入图片描述
然后我们猜测一下这个多项式是不是原方程的解呢?结果是。称这个多项式是原常微分方程的通解。
在这里插入图片描述
接下来我们猜测Fib数列的:猜测q的n次方,可以计算出来Fib数列的通项公式。
在这里插入图片描述
Fib数列前n项和公式及其证明:归纳法
在这里插入图片描述
通过通项公式得出Fib数列前n项和:
在这里插入图片描述
一个更简单的方法:方程左边加上F1再减去F1,
在这里插入图片描述
Fib数列的偶数项和:
在这里插入图片描述
总之更多的Fib性质请参考组合数学。

二、P和NP问题

某一个问题根据时间复杂度进行分类。
1、NP:时间复杂度是指数项,比如2的n次方,n!等等,都是不可以解决的问题
2、P:时间复杂度是多项式的问题,比如n的平方,logn等等。
在这里插入图片描述

三、案例分析

1、基于语料库:先搜集大量的问答对话,然后将用户输入的问题跟每个句子进行比对,返回相似度最高的问题的回答。
2、基于正则:正则表达式,自己写的一些规则。
在这里插入图片描述
基于搜索的问答系统:
1、根据英文输入进行断句。
2、对分词结果进行预处理:拼写纠错、单词原型分析、过滤口水词(er/emm/oh)、过滤特殊符号(》、?,&*%)、同义词辨析等等。
3、单词和句子用向量表示(这样就可以用数学方法处理):0/1,计数、tf-idf,w2w,s2s等等。
4、在语料库中对每一个句子进行相似度比对,求两个句子向量的欧氏距离、cosin距离、等等
在这里插入图片描述

  • 归并排序
    它的时间复杂度是nlogn,因为原问题分解成为两个子规模相等的子问题。
    在这里插入图片描述
#include <stdio.h>
#include <iostream>
#include <math.h>
#include <stdlib.h> 
#include <time.h>
using namespace std;

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void merge(int arr[],int a,int b,int c){  
	int low = a;
	int mid = b+1;
	int k = 0;
	int arr_temp[c - a + 1];
	
	while(low <= b && mid <=c){
		if(arr[low] <= arr[mid]){
			arr_temp[k++] = arr[low++];
		}else{
			arr_temp[k++] = arr[mid++];
		}
	}
	
	while(low <= b){
		arr_temp[k++] = arr[low++];
	}
	while(mid <=c){
		arr_temp[k++] = arr[mid++];
	}
	
	for(low=a,mid=0;mid<=k-1;low++,mid++){
		arr[low] = arr_temp[mid];
	}
	
}


void merge_sort(int arr[],int a,int c){
    if (a < c){
        int b =(int) (a + c) / 2;
        merge_sort(arr, a, b);
        merge_sort(arr, b+1, c);
        merge(arr, a, b, c);
    }
}

int main(int argc, char** argv) {
	srand((unsigned)time(NULL)); 
	int num = (int)rand()/1000;  //随机生成数组大小,随机生成数组元素 
	int arr[num];
	for(int i = 0; i < num  ;i++ ) {
		arr[i] = (int)rand()/1000;
	}
	
	for(int i = 0; i < num  ;i++ ) {
		cout << arr[i] << " ";
	}
	cout<<"\n";
	
	merge_sort(arr,0,num-1);
	
	for(int i = 0; i < num  ;i++ ) {
		cout << arr[i] << " ";
	}
	return 0;
}
  • 问答系统:
    1、一般方法:语料库、语句的表示、相似度
    2、知识图谱:实体抽取、关系抽取,有点像ER图
    在这里插入图片描述
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!