算法设计与分析 绪论



《算法设计与分析》  Anany Levitin著,潘彦译  清华大学出版社


1.1 什么是算法

简答介绍了算法的概念,举出了2个例子:欧几里得算法和埃拉托色尼筛。

呵呵,这里说一下之前在校内上许多计算机专业的学生转载的有趣的一个段子:"早上去图书馆一女生背着一堆书进了阅览室,结果警报响了,大妈让女生看看是哪本书把警报弄响了,那女生把书倒出来,准备一本一本的测。大妈见状急了,把书分成两份,第一份过了一下,响了。又把这一份分成两份接着测,三回就找到了,大妈用鄙视的眼神看着女生,仿佛在说连O(n)和O(log2(n))都分不清"

1,最大公约数-----欧几里得算法

gcd(m,n) = gcd(n,m mode n)

递归和非递归的实现:

package Section1;


/*绪论1.1  欧几里得算法:辗转相除求最大公约数*/

public class GCD {	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(GCD(45,255));
		System.out.println(gcd(255,45));
	}
	
	public static int GCD(int a,int b) {	//递归的形式
		if(b == 0)
			return a;
		else
			return GCD(b,a % b);//总是将较小的数放前面
			//return GCD(a % b,b);//错!!
	}
	
	public static int gcd(int a,int b){		//非递归的形式
		if(b == 0)
			return a;
		int temp;
		while(b != 0)
		{
			//temp = b % a;
			temp = a % b;//比b小,将较小的数移到后面去当b
			a = b;
			b = temp;	
		}
		return a;
	}
	
}



2,埃拉托色尼筛素数筛选方法

要筛选2--n的素数,从2到根号n,筛选,将2到根号n的倍数删除,剩余的即是素数

package Section1;

import java.util.Scanner;


/*绪论1.1  埃拉托色尼素数筛选方法的实现*/

public class PrimeFilter {		
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		int[] a;
		while(n != 0)
		{
			a = primeFilter(n);
			for(int i = 0;i < a.length;i++)
			{
				if(a[i] == 0)
					break;
				else System.out.print(a[i] + " ");
			}
			n = scan.nextInt();
		}
			
	}
		
		
	public static int[] primeFilter(int n){	//用数组返回整数n以内的所有的素数
		int[] num = new int[n];
		for(int i = 0;i < n;i++)	//全部n以内的数放在num中
			num[i] = i + 1;			
	
		for(int i = 2;i * i <= n;i++)	//开始筛选
				for(int j = i;j < n;j++)
					if(num[j] != 0 && num[j] % i == 0)
						num[j] = 0;
		
		int[] result = new int[n];		//结果数组
		int count = 0;
		for(int i = 1;i < n;i++)
			if(num[i] != 0)
				result[count++] = num[i];	
		return result;
	}

}



习题1.1  11题

模拟门的状态即可:

package Section1;


/*绪论1.1  习题11 带锁的门*/

public class LockedDoor {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] door = doorStatus(10);
		System.out.println("门的状态是:");
		for(int i = 1;i < door.length;i++)
			System.out.print(door[i] + " ");
	}
	
	public static int[] doorStatus(int n){	//n个门经过n次后各个门的状态
		int[] door = new int[n+1];//初始所有门都关着,0表示关,1表示开
		for(int i = 1; i <= n;i++)	//经过n次来改变门状态
		{
			for(int j = i;j <= n;j++)
				if(j % i == 0)//要改变的门
				{
					if(door[j] == 0)
						door[j] = 1;
					else door[j] = 0;
				}		
		}
		return door;
	}
}





1.2  算法问题求解基础

确定适当的数据结构,算法描述,正确性证明,算法效率分析,写伪代码


1.3 重要的问题类型

排序,查找;
字符串处理;
图论
排列组合
几何问题
数值


习题1.3  字符串匹配设计一个简单的算法

当然,最简单的就是蛮力匹配了,很简单就不写了。这里顺便学习和写了一下KMP算法:

书上,网上都有许多关于kmp算法的分析和论述,不再详述,只说它的核心思想,根据模式串自身的特征来提高匹配的效率,其关键在于求模式串的next函数

http://www.matrix67.com/blog/archives/115/   一个网友的kmp分析


package Section1;


/*绪论1.3  习题3 字符串匹配的kmp算法*/

public class KMP {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String S = "ababcabcacb";
		String pattern = "cabc";
		System.out.println("模式串在S中匹配的位置为: " + indexOfMatch(S,pattern));
	}

	public static int indexOfMatch(String S,String pattern){	//求模式串在S中匹配的下标(从0计)
		int index = -1;
		int[] next = next(pattern);	//!!!模式串的下标i处与S匹配失败后,将从模式串的next[i]处开始与S匹配失败的那个地方比较
		
		int j = 0 ,i = 0;//分别标记下一个要比较的位置
		
		while(j < S.length() && i < pattern.length())
		{
			if(pattern.charAt(i) == S.charAt(j))
			{
				i++;
				j++;
			}
			else if(i == 0)		//不匹配,而且是第一个位置就不匹配
				j++;
			else				//不匹配,且不是第一个位置
				i = next[i];	
		}
		if(i == pattern.length())
			return j-pattern.length();	//返回在S中第一个匹配的位置;
		else return index;
	}
	
	
	private static int[] next(String pattern){		//求模式串的next函数
		int[] next = new int[pattern.length()];
		int i = 0;
		while(i < next.length)		//求每个位置的next值
		{
			if(i == 0)
				next[i] = 0;
			else
			{
				for(int n = 0;n < i;n++)
					if(pattern.substring(0, n).equals(pattern.substring(i-n, i))
							&& pattern.charAt(n) != pattern.charAt(i))
						next[i] = n;
			}
			i++;
		}
		return next;
	}
}



毫无技巧处理的蛮力匹配时间复杂度是mn,而kmp可将时间效率提高到m+n。其实写一下kmp算法主要是了解一下这种处理字符串的思想和技巧,时间久了估计还是忘了,关键是这种思想要知道。



1.4  基本的数据结构

习题7,如何用下列数据结构实现ADT优先队列:

无序数组
有序数组
二叉查找树 

实现方法略,说一点,数据结构的抽象!

转载于:https://www.cnblogs.com/jmzz/archive/2011/06/05/2073354.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用Java编写的几种经典问题算法: 1.设a[0:n-1]是一个有n个元素的数组,k(0<=k<=n-1)是一个非负整数。 试设计一个算法将子数组a[0:k]与a[k+1,n-1]换位。要求算法在最坏情况下耗时O(n),且只用到O(1)的辅助空间。 2.在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分和最大得分,并分析算法的计算复杂性。 3.设磁盘上有n个文件f1,f2,…,fn,每个文件占用磁盘上的1个磁道。这n个文件的检索概率分别是p1,p2,…,pn,且 =1。磁头从当前磁道移到被检信息磁道所需的时间可用这2个磁道之间的径向距离来度量。如果文件fi存放在第i道上,1≦i≦n,则检索这n个文件的期望时间是对于所有的i<j,time+=pi*pj*d(i,j) 。其中d(i,j)是第i道与第j道之间的径向距离|i-j|。磁盘文件的最优存储问题要求确定这n个文件在磁盘上的存储位置,使期望检索时间达到最小。试设计一个解决此问题的算法,并分析算法的正确性与计算复杂度。 4.最小重量机器设计问题。设某一机器由n个部件组成,每一种部件可以从m个不同的供应商处购得。设wij是从供应商j处购得的部件i的重量,cij是相应的价格。试设计一个算法,给出总价格不超过c的最小重量机器设计

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值