java算法:一流的ADT

java算法:一流的ADT

客户程序处理的应用越来越复杂,而ADT通过构建越来越强大的抽象层帮助管理创建客户程序的复杂性。在这个过程中,可能会出现隐患。一流数据类型是我们能在程序中使用的方式与使用基本数据类型的方式相同的数据类型。如果只能通过接口来访问,那就是一流的ADT。

写一个程序计算第N个单位根并把他们每个都提升到N次幂来检查计算。

例1:复数的ADT接口

Java代码 复制代码
  1. classCompleximplementsCloneable{
  2. Complex(doublere,doubleim)
  3. doublere()
  4. doubleim()
  5. Complexmult(Comlexrhs)
  6. publicObjectclone()
  7. publicStringtoString()
  8. }
class Complex implements Cloneable{
	Complex(double re, double im)
	double re()
	double im()
	Complex mult(Comlex rhs)
	public Object clone()
	public String toString()
}

例2:复数的ADT实现

Java代码 复制代码
  1. classCompleximplementsCloneale{
  2. privatedoublere,im;
  3. Complex(doublere,doubleim){
  4. this.re=re;
  5. this.im=im;
  6. }
  7. doublere(){
  8. returnre;
  9. }
  10. doubleim(){
  11. returnim;
  12. }
  13. voidadd(Complexrhs){
  14. re=re()+rhs.re();
  15. im=im()+rhs.im();
  16. }
  17. voidmult(Complexrhs){
  18. doublet=re();
  19. re=re()*rhs.re()-im()*rhs.im();
  20. im=t*rhs.im()+im()*rhs.re();
  21. }
  22. publicStringtoString(){
  23. returnre()+""+im();
  24. }
  25. }
class Complex implements Cloneale{
	private double re, im;
	Complex(double re, double im){
		this.re = re;
		this.im = im;
	}
	double re(){
		return re;
	}
	double im(){
		return im;
	}
	void add(Complex rhs){
		re = re() + rhs.re();
		im = im() + rhs.im();
	}
	void mult(Complex rhs){
		double t = re();
		re = re() * rhs.re() - im() * rhs.im();
		im = t * rhs.im() + im() * rhs.re();
	}
	public String toString(){
		return re() + " " + im();
	}
}

例3:复数驱动器(单位根)

Java代码 复制代码
  1. publicclassRootsOfUnity{
  2. publicstaticvoidmain(Stringargs[]){
  3. intN=100;
  4. System.out.println(N+"rootsofunity.");
  5. for(intk=0;k<N;k++){
  6. doublex=Math.cos(2.0*Math.PI*k/N);
  7. doubley=Math.sin(2.0*Math.PI*k/N);
  8. Complexc=newComplex(x,y);
  9. System.out.println(k+":"+c);
  10. Complexz=(Complex)c.clone();
  11. for(intj=0;j<N-1;j++){
  12. z.mult(c);
  13. }
  14. System.out.println(""+z);
  15. }
  16. }
  17. }
public class RootsOfUnity{
	public static void main(String args[]){
		int N = 100;
		System.out.println(N + " roots of unity.");
		for(int k = 0; k < N; k++){
			double x = Math.cos(2.0 * Math.PI * k / N);
			double y = Math.sin(2.0 * Math.PI * k / N);
			Complex c = new Complex(x,y);
			System.out.println(k + " : " + c);
			Complex z = (Complex)c.clone();
			for(int j = 0; j < N-1; j++){
				z.mult(c);
			}
			System.out.println(" " + z);
		}
	}
}

当使用静态的带有两个参数的方法时,每次执行算术运算以及扩展运算都不得不创建一个新的Complex,这可能留下很多要被垃圾收集器回收的对象。当使用类方法时,则不需要。

如计算:z的N次方:

Java代码 复制代码
  1. floatz=t;
  2. for(intj=0;j<N-1;j++){
  3. z*=t;
  4. }
float z = t;
for(int j = 0; j < N-1; j++){
	z *= t;
}

如果是Complex对象:

Java代码 复制代码
  1. Complexz=t;
  2. for(intj=0;j<N-1;j++){
  3. z.mult(t);
  4. }
Complex z = t;
for(int j = 0; j < N-1; j++){ 
	z.mult(t);
}

在这里可能会犯错误,因为z和t是对同一个复数对象的引用,而不是不同复数的对象。结果不是z的N次方,而是z的平方的N次方。使用clone()很好的解决了这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值