算法

java算法----算法的时间复杂度

独自空忆成欢 提交于 2020-02-08 04:52:20
一. 度量一个程序(算法)执行时间的两种方法 1.事后统计的方法 这种方法可行,但有两个问题: 一是想要对设计的算法的运行性能进行评测,需要实际运行改程序; 二十所得时间的统计量依赖于计算机硬件, 软件等环境因素, 这种方式, 要在同一台计算机的相同状态下运行,才能比较哪个算法速度更快. 2.事前估算的方法 通过分析算法的 时间复杂度 来判断哪个算法更占优 二. 从时间频度到时间复杂度 1.时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。 一个算法中的语句执行次数称为语句频度或时间频度 。记为T(n),n表示语句的执行次数。 时间频度案例说明: 2.时间复杂度 前面提到的时间频度T(n)中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律,为此我们引入时间复杂度的概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O

大熊君说说JS与设计模式之------策略模式Strategy

十年热恋 提交于 2020-02-08 04:14:59
一,总体概要 1,笔者浅谈 策略模式,又叫算法簇模式,就是定义了不同的算法,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 策略模式和 工厂模式 有一定的类似,策略模式相对简单容易理解,并且可以在运行时刻自由切换。工厂模式重点是用来创建对象。 策略模式应用比较广泛,比如:我们现在要定义数据交换格式,现有三种方案可选1,XML 2,JSON 3,CSV就 可以使用策略模式实现。 这里我要强调的是------ 我们是针对不同数据源选择不同方案,针对的都是同一事物做相同意图的操作只是方案不同。 代码实现如下: 1 var dataSourceVendor = { 2 xml : { 3 get : function(){ 4 console.log("XML数据源") ; 5 } 6 } , 7 json : { 8 get : function(){ 9 console.log("JSON数据源") ; 10 } 11 } , 12 csv : { 13 get : function(){ 14 console.log("CSV数据源") ; 15 } 16 } 17 } ; 18 console.log("选择的数据源:" + dataSourceVendor["json"]["get"]()) ; 注意到了吧,它们的接口是一致的,也就是意图操作一致的,只是实现不同。

第23讲:Strategy 策略模式

时间秒杀一切 提交于 2020-02-08 03:42:39
2006.9.25 李建忠 算法与对象的耦合 对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱…… 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题? 意图(Intent) 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户而变化。 ——《设计模式》GoF 例说Strategy模式应用 这个程序有两个可能的变化点:当枚举类型增加时,即处理的方法增加,那么Process函数需要修改补充一个if else分支;当我们想对分支1的处理ProcessA进行更改时,也要对Process函数进行修改。 针对上面的问题,我们首先想到的是把ProcessA写成受保护的虚函数(在OO中我们一般把虚函数都写成受保护的函数,因为它是能改变类的行为的函数,一般情况下只应该作为子类和父类之间的协议出现)。 Strategy模式的设计 把Cart类和ProcessStrategy类作为对象组合的方式使用。IProcessStrategy表达的是一个算法抽象。 抽象和具体算法 客户程序 这样算法就可以动态地去改变了

策略模式

不问归期 提交于 2020-02-08 01:12:44
一、概念 策略模式(Strategy): 它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.) 图1 策略模式类图  优点:   1、 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。   2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。 3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。   缺点:   1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。 2、 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。(这本身没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化的减轻了客户端的压力。) 参考阅读: 1. 2. 二、我的理解 其实这个策略模式和简单工厂模式一样

数据结构与算法(冒泡排序)

↘锁芯ラ 提交于 2020-02-07 23:36:40
冒泡排序 冒泡排序是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。遍历数列的工作是重复的进行直到没有在需要的交换,也就是说该数列已经排序完成,这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 冒泡算法的运作如下: 比较相邻的元素,如果第一个元素大于第二个元素(升序),就交换它们两个。 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对,这步完成后,最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个 持续每次越来越少的元素重复上面的步骤,直到没有任何一堆数字需要比较。 冒泡算法分析 交换过程图示( 第一次 ): 那么我们需要进行n-1次冒泡过程,每次对应的比较次数如下图所示: Pass Comparisons 1 n-1 2 n-2 3 n-3 … … n-1 1 代码实现 def bubble_sort(alist): """冒泡排序""" for j in range(len(alist)-1): for i in range(len(alist)-j-1): if alist[i] > alist[i+1]: alist[i], alist[i+1] = alist[i+1], alist[i] return alist 时间复杂度 最优时间复杂度:O(n

十大经典排序排序算法学习总结(C++实现)

倖福魔咒の 提交于 2020-02-07 21:48:55
常用算法总结记录一下,否则会变得只记得算法名,也可能名都记不住。 图片和动图(我不会画),但我从网上找到了资源。 代码我用C/C++实现的,运行结果都有验证。 时间复杂度和空间复杂度我还没有研究,各种地方抄到的,以后有时间再研究,如果有错误,还请指正。   In/out-place: 不占/占额外内存 1.冒泡排序  冒泡排序算法原理:   比较相邻的元素。如果第一个比第二个大,就交换他们两个。   循环重复以上步骤,直到没有任何一对元素需要比较。   还有位前辈也画的挺好,我也把图贴过来了。  冒泡排序时间复杂度、空间复杂度、稳定性   冒泡排序时间复杂度:最好 O( n) 最坏 O( n 2 ) ,平均 O( n 2 ) 。   冒泡排序空间复杂度: O( 1 ) 。   冒泡排序是一种 稳定 排序算法。  冒泡排序源码实现 1 #include <iostream> 2 using namespace std; 3 4 5 template <typename T> 6 void BubbleSort(T arr[], int len) 7 { 8 if (NULL == arr || 0 >= len) 9 return; 10 11 int i = 0, j = 0, nFlag = 0; 12 13 for (i = 0; i < len - 1; i++) 14 {

(转)TCP的滑动窗口与拥塞窗口(主要讲慢启动,拥塞避免,快重传,快恢复)

会有一股神秘感。 提交于 2020-02-07 21:42:39
原地址 https://blog.csdn.net/ligupeng7929/article/details/79597423 因此我们先了解一下16位的窗口大小究竟有什么作用。 窗口分为滑动窗口和拥塞窗口。 滑动窗口是接受数据端使用的窗口大小,用来告知发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的。 那么对于数据的发送端就是拥塞窗口了,拥塞窗口不代表缓存,拥塞窗口指某一源端数据流在一个RTT内可以最多发送的数据包数 一、滑动窗口 滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的可以接受缓冲区大小(这个字段越大说明网络吞吐量越高),从而控制发送方的发送速度,不过如果接收端的缓冲区一旦面临数据溢出,窗口大小值也会随之被设置一个更小的值通知给发送端,从而控制数据发送量(发送端会根据接收端指示,进行流量控制)。 对ACK的再认识,ack通常被理解为收到数据后给出的一个确认ACK,ACK包含两个非常重要的信息: 一是期望接收到的下一字节的序号n,该n代表接收方已经接收到了前n-1字节数据,此时如果接收方收到第n+1字节数据而不是第n字节数据,接 收方是不会发送序号为n+2的ACK的。举个例子,假如接收端收到1-1024字节,它会发送一个确认号为1025的ACK,但是接下来收到的是 2049-3072,它是不会发送确认号为3072的ACK

左神算法笔记(十三)——Manacher算法

ぃ、小莉子 提交于 2020-02-07 11:18:59
在一个字符串中找到最长的回文字符串 以每个位置作为中心,向两边扩展,可以确定奇回文,但是偶回文无法这样做。 解决方法:在字符串中间及两边插入某种字符,此时可以按照这种方法进行扩展。此时无论奇回文还是偶回文都可以找到。 例如11211,此时添加任意字符在两边#1#1#2#1#1#此时均可以进行回文判断。 补充概念: 回文直径:以一个位置为中心,扩出来整个串的长度为回文直径 回文半径:以一个位置为中心,扩出来半个串长度为回文半径 回文数组:对于字符串而言,从0位置开始,一直到最后,新建一个数组,数组中保存对应位置的回文半径。 最右回文右边界:所有回文半径中,最靠右的边界,回文右边界只要没更新,记录最早取得此处的回文中心。 Manacher算法详解: Manacher在向外扩展的过程整体跟之前的算法相似,但是有加速。 回文右边界R不包含位置i,此时暴力扩展,直到R包含i。 i位置在回文有边界内时,知道了回文右边界可以知道回文左边界,对称中心为c,此时关于c做i的对称点i‘,若i‘的回文彻底在c为中心的回文里面,此时i的回文半径和i’的回文半径相同。 i位置的对称位置i’的回文半径越过了以c为中心的左边范围。(i‘扩出的范围以c为中心的回文没包住,存在一部分在回文直径外面)此时i’的回文半径是i-R。 正好i‘的回文半径正好跟左边L相等,此时可以直到i的回文半径大于等于i-R

KMP字符串匹配算法

僤鯓⒐⒋嵵緔 提交于 2020-02-07 09:22:57
昨天意外的翻开一本搜索引擎的书,看到了KMP算法,很早以前就听过KMP算法,但是没有深究,最近在搞搜索,所以想深入学习一下 KMP算法 。KMP算法是一种改进的字符串匹配算法。KMP算法的核心是通过匹配表来提高匹配效率,理解了匹配表就基本理解了KMP算法。核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。我认为优秀算法的根本是减少不必要的重复计算从而提升效率。 介绍两个概念: 前缀:除字符串的最后一个字符外,所有前缀组合 后缀:除了字符串的第一个字符外,所有后缀组合 例如:Google,前缀:G、Go、Goo、Goog、Googl 后缀:o、oo、oog、oogl、oogle 那么匹配表怎么算呢,找到” 前缀和后缀集合中最长匹配的字符串的长度 “。 例如:abababca a的前缀后缀都为空 L=0 ab的前缀为a后缀为b L=0 aba的前缀a、ab后缀a、ba,L=1 abab的前缀a、ab、aba后缀b、ab、bab,L=2 ababa的前缀a、ab、aba、abab后缀baba、aba、ba、a,L=3 ababab的前缀a、ab、aba、abab、ababa后缀babab、abab、bab、ab、b,L=4 abababc的前缀a、ab、aba、abab、ababa、ababab后缀bababc、ababc、babc、abc、bc、c,L=0

algorithm@ KMP

北战南征 提交于 2020-02-07 09:21:39
一. KMP算法 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,简称KMP算法。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。 二. KMP算法的意义 先举一个简单模式匹配的例子,给定字符串T=“abababca”,S=“bacbababaabcbab”,判断T是否是S的子串,如果用暴力扫描的话,就是拿着T字符串从S的头扫到尾。这样的时间复杂度最坏情况下是O(n*m),其中n和m分别是主串和模式串的长度。而KMP算法的时间消耗是O(n+m)的,至于为什么这样,下面再说。 三. KMP算法的核心 KMP的核心就是一张表,我们称之为部分匹配表,起初我看这张表的时候也是云山雾绕,不知所云,部分匹配表是为模式串T专门设计的,T中每个字符对应着一个整数值,(这个地方也是困扰了我很久),现在我尽可能说得明白一些。首先下面附上一张T为“abababca”的部分匹配图,让大家“先睹为快”,看看部分匹配表是个什么东东。 好了,现在我们有了一个含有8个字符的模式串T,那么最后一行的value值是怎么得来的呢?别急,我先介绍相关概念:前缀和后缀,就拿字符串”abca“来说,”abca“的前缀有{a,ab,abc},