算法设计的几种思维(编程珠玑算法学习总结)
2016-01-14 22:21
405 查看
原题是一个一维模式识别的题:求n个浮点数向量中连续若干个子向量中的最大和。
在书中共讨论了四种算法:
第一种算法是最笨的办法,利用三重循环求出每一个子向量的和,然后求出其中的最大值,其时间复杂度为O(n3)
int maxvect(int *x,int n)
{
int maxsofar=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum=0;
for(int k=i;k<=j;k++)
{
sum+=x[k];
}
maxsofar=max(maxsofar,sum);
}
}
return maxsofar;
}
第二种算法分了两种,其一是在求x[1...i]时利用x[1...i-1]的值,则减少了一层内循环,第二种是将计算的和的子向量存储在一个数组中,又可称为累积表,这样每个子向量的和都可由累计表中两项相减得到。这两种算法的时间复杂度都是O(n2)
第一种:
int maxvect(int *x,int n)
{
int maxsofar=0;
for(int i=0;i<n;i++)
{
sum=0;
for(int j=0;j<n;j++)
{
sum+=x[j];
maxsofar=max(maxsofar,sum);
}
}
return maxsofar;
}
第二种:
int maxvect(int *x,int n)
{
int maxsofar=0;
int *cumarr=new int[n+1];
cumarr[0]=0;
for(int i=0;i<n;i++)
{
cumarr[i+1]=cumarr[i]+x[i];
}
for(int i=0;i<n;i++)
{
sum=0;
for(int j=i;j<n;j++)
{
sum=cumarr[j+1]-cumarr[i];
maxsofar=max(maxsofar,sum);
}
}
return maxsofar;
}
第三种算法为分治算法,即分别求两个子向量的最大和,然后在划分,最后合并起来,它的时间复杂度为O(nlogn),在《算法导论》也提到了使用分治算法解这个题的详细分析过程。这里我没有仔细研究。
第四种算法扫描算法。它的思想是只扫描一次,记下遇到的子向量的总和最大的子向量,它的问题是如何有X[0...i-1]扩展为X[0...i],,它的做法是设立一个结束标志maxending,它的时间复杂度为O(n)
int maxvect(int *x,int n)
{
int maxsofar=0;
int maxendnig=0;
for(int i=0;i<n;i++)
{
maxending=max(maxending+x[i],0);
maxsofar=max(maxsofar,maxending);
}
}
return maxsofar;
}
在实际比较几种算法的运行时间时,我非常直观的体会的算法对于程序运行性能的影响。我用了10000个数的数组,第四种算法几乎瞬间完成,而第一种算法就需要若干分钟,具体性能比较我没有截图,不过《编程珠玑》第8章有详细的对比,有兴趣的查看,数据量越大,这种差距越大。
最后书中总结了几种算法设计的技术:
1.保存中间状态,避免重复计算。
2.预处理数据,存入一个结构中,如算法2中的累计表,是非常常用的一个手段。
3. 分治算法。
3. 扫描算法。利用X[0...i],扩展到X[0...i+1]
相关文章推荐
- Spring+EhCache缓存实例(详细讲解+源码下载)
- C语言中的顺序点
- Win7下Visual Studo 2010安装图解教程
- django 小技巧
- Restful形式接口文档生成之Swagger与SpringMVC整合手记
- 以太坊未来的 POS 协议:Casper
- 用最大堆模拟最大优先级序列(Python实现)
- Spring+Mybatis+Struts2框架搭建
- Python函数
- struts2 显示表格
- Keil MDK 5代码补全功能设置
- Java Swing JTable 表格【16:复选框JCheckBox作为表格元素】
- ThinkPHP 3.2.3 简单后台模块开发(一)常用配置
- django 学习-12 Django表单 初步
- 公交车到站预测1----python处理csv文件
- 利用pandas进行数据分组及可视化
- python-列表与元组
- 初学java——java编程发展方向,JDK和Java源文件与Java字节码文件的关系
- 用keytool将eclipse下的apk签名文件转.p12文件步骤
- java中的集合和视图