问题
- 一个池塘很多种类鱼,鱼吃东西,养大之后卖,卖了可以再买鱼
- 购买逻辑貌似有点问题。没有考虑最优金额之类的。java和ts语法使用的也磕磕碰碰
Java版本
思路
- 鱼的价格根据种类固定,鱼的卖出年龄根据种类固定(或者根据重量决定?)
- 创建一个池塘类finish来初始化池塘;创建一个抽象类absFinish来规范所有种类鱼的属性和行为
- 池塘里面的鱼统一放入一个数组中存储,每年遍历年龄是否达到,达到则卖出。不达到则年龄增加
感想
- 对Java太久没用了。语法不熟悉,特别是使用数组的时候发现好多数组类型,List,ArrayList,Object[]都试过。
- 本来选定了数组,但是后来发现删除数组在List之类的类型中好像不能删除最后一个(其他的使用arr[i]=arr[i+1]这种方式伪删除),最后选了ArrayList
package test; import java.util.ArrayList; import java.util.List; public class finish { protected static Integer sum=0; // 口袋里面的钱 public static Integer finishNum=0; // 池塘的鱼数 protected static ArrayList<Object> arr; public static void main(String []args) { // 鱼的种类,年龄,单价,数量,最大年龄 crucianCarp a=new crucianCarp("鲫鱼",1,null,10,4); grassCarp b=new grassCarp("草鱼",3,null,3,4); // ""指的是String,''指的是char类型 bighead c=new bighead("鳙鱼",4,null,4,5); // 共17条 arr=new ArrayList<>(); arr.add(a); arr.add(b); arr.add(c); buy(4); // 预测n年后的收益 System.out.print("钱包余额:"); System.out.println(sum); System.out.print("还剩下的鱼的数量:"); System.out.print(finishNum); } // 卖鱼,买鱼,设置期限(假设买到的鱼都是0年的) public static void buy(Integer n) { while(n-- > 0) { // 卖出 for(int i=0;i<arr.size();i++) { absFinish obj=((absFinish) arr.get(i)); if(obj.getMaxAge()<=obj.getAge()) { sum+=(obj.getPrice()*obj.getNum()); arr.remove(i); i--; finishNum-=obj.getNum();// 减少鱼数 }else { obj.SetAge();//年龄增加 } } System.out.println("本轮余额:"); System.out.println(sum); // 购买(购买策略。。先买池塘里面还有的鱼,假设市场里面的鱼是无限量的) Integer len=arr.size(); for(int j=0;j<len;j++) { Integer buyNum = 0; switch (j%3) { case 0: crucianCarp caseA=new crucianCarp(null,0,null,0,null); // 本轮购买数量 buyNum=(int) Math.floor(sum/caseA.getPrice()); if(buyNum>0) { caseA.setNum(buyNum); // 减少余额 sum-=caseA.getPrice()*buyNum; arr.add(caseA); } break; case 1: grassCarp caseB=new grassCarp(null,0,null,0,null); // 本轮购买数量 buyNum=(int) Math.floor(sum/caseB.getPrice()); if(buyNum>0) { caseB.setNum(buyNum); // 减少余额 sum-=caseB.getPrice()*buyNum; arr.add(caseB); } break; case 2: bighead caseC=new bighead(null,0,null,0,null); // 本轮购买数量 buyNum=(int) Math.floor(sum/caseC.getPrice()); if(buyNum>0) { caseC.setNum(buyNum); // 减少余额 sum-=caseC.getPrice()*buyNum; arr.add(caseC); } break; default: break; } finishNum+=buyNum; } } } } // 抽象类 abstract class absFinish extends finish{ private String name; private Integer price; private Integer age; private Integer num; // 鱼的数量 private Integer maxAge; // 构造器,如js的construtor public absFinish(String name,Integer age,Integer price,Integer num,Integer maxAge) { this.name=name; this.age=age; this.price=price; this.num=num; this.maxAge=maxAge; } // 获取鱼的年龄 public final Integer getAge() { return age; } // 获取鱼的成熟年龄 public final Integer getMaxAge() { return maxAge; } // 获取鱼的数量 public final Integer getNum() { return num; } // 设置鱼的数量 public final void setNum(Integer num) { this.num=num; } // 过了一个月,年龄增加 public final void SetAge() { age++; } // 获取鱼的价格 public final Integer getPrice() { return price; } // 获取鱼的名称 public final String getName() { return name; } } // 鲫鱼 class crucianCarp extends absFinish{ public crucianCarp(String name,Integer age,Integer price,Integer num,Integer maxAge) { super(name="鲫鱼",age,price=20,num,maxAge=4); // 增加鱼的总数 finishNum+=num; } } //草鱼 class grassCarp extends absFinish{ public grassCarp(String name,Integer age,Integer price,Integer num,Integer maxAge) { super(name="草鱼",age,price=10,num,maxAge=4); finishNum+=num; } } //鳙鱼 class bighead extends absFinish{ public bighead(String name,Integer age,Integer price,Integer num,Integer maxAge) { super(name="鳙鱼",age,price=35,num,maxAge=5); finishNum+=num; } }ts版本
思路
- 创建一个池塘类finish来初始化池塘;创建一个抽象类absFinish来规范所有种类鱼的属性和行为
- 导出池塘类finish,在index.js中通过require导入该模块
- tsc finish.ts编译ts文件,使用node index.js来启动js文件,初始化池塘。
缺点
- switch中根据n%3来决定创建的鱼的实例,但是如果有十几种鱼就要写十几个case?但是直接把字符串放入数组又不行,又不能使用eval("new bighead('苹果')")这种形式。
- sum和finishNum由于会在absFinish中用到,所以我放到finish类的外部。但是创建多个鱼塘的时候,就会导致使用的是同一个变量。。
// index.js var {finish,crucianCarp,grassCarp,bighead}=require('./test') // 创建一个池塘 var fi=new finish(6) let a=new crucianCarp(undefined,1,undefined,10,undefined) let b=new grassCarp(undefined,3,undefined,3,undefined) let c=new bighead(undefined,4,undefined,4,undefined) fi.arr.push(a,b,c) fi.init() // 此时是共有变量,不是预期效果 var qq=new finish(2) let d=new crucianCarp(undefined,1,undefined,10,undefined) qq.arr.push(d) qq.init()- 下面是ts文件
// finish.ts let finishNum:number = 0; // 鱼的数量 let sum:number = 0; // 钱包余额 /* 缺点很明显,但是我自己现在想不到需要怎么优化 */ class finish{ arr:Array<absFinish> = []; // 目前的鱼 year:number=0; constructor(year:number){ this.year=year; } init(){ console.log("以前:","余额:",sum," 鱼的数量:",finishNum) this.buy(this.year) //6: 余额5,数量24 console.log("之后:","余额:",sum," 鱼的数量:",finishNum) } // 开始买卖 buy(y:number):void{ while(y-->0){ // 卖出鱼 for(var i=0;i<this.arr.length;i++){ if(this.arr[i].getAge()>=this.arr[i].getMaxAge()){ let num:number=this.arr[i].getNum(); sum+=num*(this.arr[i].getPrice() as number); finishNum-=num; console.log(this.arr[i],sum) this.arr.splice(i,1) i--; }else{ this.arr[i].setAge();// 年龄增加 } } // 买鱼 (购买策略是 y%3,3指的是鱼的种类) let len=this.arr.length for(var j=0;j<len;j++) { let buyNum:number = 0; switch (y%3) { // 在case中使用let会报错,因为eslint规则 case 0: var caseA:crucianCarp=new crucianCarp(undefined,0,undefined,0,undefined); // 本轮购买数量 buyNum=Math.floor(sum/(caseA.getPrice() as number)); if(buyNum>0) { caseA.setNum(buyNum); // 减少余额 sum-=(caseA.getPrice() as number)*buyNum; this.arr.push(caseA); } break; case 1: var caseB:grassCarp=new grassCarp(undefined,0,undefined,0,undefined); // 本轮购买数量 buyNum=Math.floor(sum/(caseB.getPrice() as number)); if(buyNum>0) { caseB.setNum(buyNum); // 减少余额 sum-=(caseB.getPrice() as number)*buyNum; this.arr.push(caseB); } break; case 2: var caseC:bighead=new bighead(undefined,0,undefined,0,undefined); // 本轮购买数量 buyNum=Math.floor(sum/(caseC.getPrice() as number)); if(buyNum>0) { caseC.setNum(buyNum); // 减少余额 sum-=(caseC.getPrice() as number)*buyNum; this.arr.push(caseC); } break; default: break; } finishNum+=buyNum; } } } } // 抽象类 abstract class absFinish{ private name:string; private price?:number; // 不一定需要该属性,那么在return应该是联合类型 private age:number; private num:number; // 鱼的数量 private maxAge:number; // 构造器 constructor(name:string,age:number,price:number,num:number,maxAge:number) { this.name=name; this.age=age; this.price=price; this.num=num; this.maxAge=maxAge; // 增加鱼的总数 finishNum+=num; } // 获取鱼的年龄 getAge():number { return this.age; } // 获取鱼的成熟年龄 getMaxAge():number { return this.maxAge; } // 获取鱼的数量 getNum():number { return this.num; } // 设置鱼的数量 setNum(num:number):void { this.num=num; } // 过了一个月,年龄增加 setAge():void { this.age++; } // 获取鱼的价格 getPrice():number|undefined { return this.price; } // 获取鱼的名称 getName():string { return this.name; } } // crucianCarp class crucianCarp extends absFinish{ constructor(name:string='鲫鱼',age:number=0,price:number=20,num:number,maxAge:number=4){ super(name,age,price,num,maxAge) } } // grassCarp class grassCarp extends absFinish{ constructor(name:string="草鱼",age:number=0,price:number=10,num:number,maxAge:number=4){ super(name,age,price,num,maxAge) } } // bighead class bighead extends absFinish{ constructor(name:string="鳙鱼",age:number=0,price:number=35,num:number,maxAge:number=5){ super(name,age,price,num,maxAge) } } export {finish,bighead,grassCarp,crucianCarp}java和javascript的区别与相同点
- java中使用null作为无效的参数默认值,而javascript中使用undefined(不能使用null),java中没有undefined这个类型
- Java对于类型的检查貌似更加严格?使用System.out.println()不能把两种类型的变量凑在一起。而ts使用console.log()打印两种类型明显可以。
- 都使用super()来调用父类的构造函数。ts可以通过super.xx()来调用父类的方法。但是不可以通过super.xx来获取父类的属性,解决方法是把属性挂载到父类的原型链上,子类就可以通过this来调用变量
本文使用 mdnice 排版