对于link中给出的第III部分分配,
第三部分:将海洋转换为游程编码
编写一个RunLengthEncoding构造函数,该构造函数将Ocean对象作为其唯一参数,并将其转换为Ocean的游程长度编码。为此,您需要在Ocean类中实现sharkFeeding()方法,该方法告诉您给定的鲨鱼有多饿。仔细阅读Ocean.java和RunLengthEncoding.java,以获取有关您必须使用哪些方法的说明。
写。
Ocean类的字段必须是私有的,因此RunLengthEncoding构造函数将依赖width(),height(),starveTime(),cellContents()和sharkFeeding()方法。
测试中
您的RunLengthEncoding实现必须具有check()方法,
它遍历游程编码并检查其有效性。
具体来说,如果出现以下任何情况,它将打印警告消息
发现问题:
如果两个连续运行的内容类型完全相同。
例如,先执行“ F12”再执行“ F8”是非法的,因为
他们应该已经合并到一个单一的运行。 (不要忘记,
不过,鲨鱼是根据它们最近食用的时间来划分的。)
如果所有游程长度的总和不等于
海洋;即宽度乘以高度。
您可能会发现check()方法对于调试您的计算机非常有用。
第IV部分中的RunLengthEncoding构造函数以及addFish()和addShark()。
这是不完整的解决方案:
class RunLengthEncoding {
/**
* Define any variables associated with a RunLengthEncoding object here.
* These variables MUST be private.
*/
private DList2 list;
private long sizeOfRun;
private int width;
private int height;
private static int starveTime;
/**
* The following method is required for Part III.
*/
/**
* RunLengthEncoding() (with one parameter) is a constructor that creates
* a run-length encoding of an input Ocean. You will need to implement
* the sharkFeeding method in the Ocean class for this constructor's use.
* @param sea is the ocean to encode.
*/
public RunLengthEncoding(Ocean sea) {
this.list = new DList2();
this.width = sea.getWidth();
this.height = sea.getHeight();
RunLengthEncoding.starveTime = Ocean.getStarvationTime();
int index =0;
int sizeOfTheOcean = sea.getWidth() * sea.getHeight();
int sameNeighborCount =1;
TypeAndSize typeAndSizeObject = null;
while(index < sizeOfTheOcean){
if(isSameNeighbor(sea,index)){
sameNeighborCount++;
}else{
typeAndSizeObject = sea.cellContents((index/sea.getWidth()), Utility.mod(index, sea.getWidth())).getTypeAndSize(sameNeighborCount);
this.list.insertFront(typeAndSizeObject.type, typeAndSizeObject.runLength);
if(typeAndSizeObject.type == Ocean.SHARK){
//How do i capture hungerlevel of shark because TypeAndSize only has 2 members
}
this.sizeOfRun++;
sameNeighborCount = 1;
}
index++;
}
check();
}
/**
* This method checks the type of any two adjacent cells
* @param sea
* @param index
* @return boolean
*/
private boolean isSameNeighbor(Ocean sea, int index){
Critter creature1 = sea.cellContents((index/sea.getWidth()), Utility.mod(index, sea.getWidth()));
Critter creature2 = sea.cellContents(((index+1)/sea.getWidth()), Utility.mod(index+1, sea.getWidth()));
if( creature1.equals(creature2) ){
return true;
}
return false;
}
/**
* check() walks through the run-length encoding and prints an error message
* if two consecutive runs have the same contents, or if the sum of all run
* lengths does not equal the number of cells in the ocean.
*/
public void check() {
DListNode2 node = this.list.sentinel.next;
int sumOfAllRunLengths = 0;
while(node != this.list.sentinel){
if(node.runObject.type == node.next.runObject.type){
System.out.println("Error message - Two consecutive runs have the same contents\n");
return;
}else{
node = node.next;
}
}
node = this.list.sentinel.next;
while(node != this.list.sentinel){
sumOfAllRunLengths += node.runObject.runLength;
node = node.next;
}
if(sumOfAllRunLengths != this.width*this.height){
System.out.println("Error Message");
}
}
}
==========================
/* Critter.java */
package Project1;
/**
* The abstract class Critter defines a base class for any creature
* that can exist at a specific location in the ocean.
* @author mohet01
*
*/
abstract class Critter {
/**
* Below data member defines a location of a Critter in an Ocean
*/
Point location;
public Critter(int x, int y){
location = new Point(x,y);
}
public Point getLocation(){
return location;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
return true;
}
public abstract TypeAndSize getTypeAndSize(int sameNeighborCount);
/**
* This method computes the behavior of the Critter in the Ocean.
* Computes new value of location property of Critter.
* No operation is performed as this is a base class.
*/
public abstract Critter update(Ocean currentTimeStepSea);
}
=======================
/* Shark.java */
package Project1;
/**
* The Shark class defines behavior of a Shark in an Ocean.
* @author mohet01
*
*/
class Shark extends Critter{
/**
* Below data member specifies the hunger of each shark you add to the
* ocean.
*/
private int hungerLevel;
/**
* Constructor will create a new location for Shark
* @param x
* is the x-coordinate of location(which can be EMPTY) of Shark
* @param y
* is the y-coordinate of location(which can be EMPTY) of Shark
*/
public Shark(int x, int y, int hungerLevel){
super(x,y);
//Sharks are well-fed at birth
this.hungerLevel = hungerLevel;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
if(this.hungerLevel != ((Shark)obj).hungerLevel)
return false;
return true;
}
/**
* This method converts the Ocean object of a cell to TypeAndSize object.
*
*/
@Override
public TypeAndSize getTypeAndSize(int sameNeighborCount){
TypeAndSize object = new TypeAndSize(Ocean.SHARK, sameNeighborCount);
return object;
}
/**
* The following method is required for Part III.
*/
/**
* sharkFeeding() returns an integer that indicates the hunger of the shark
* in cell (x, y), using the same "feeding" representation as the parameter
* to addShark() described above. If cell (x, y) does not contain a shark,
* then its return value is undefined--that is, anything you want.
* Normally, this method should not be called if cell (x, y) does not
* contain a shark. You will need this method to help convert Oceans to
* run-length encodings.
* @param x is the x-coordinate of the cell whose contents are queried.
* @param y is the y-coordinate of the cell whose contents are queried.
*/
public int sharkFeeding() {
return this.hungerLevel;
}
}
=============================
/* TypeAndSize.java */
/* DO NOT CHANGE THIS FILE. */
/* YOUR SUBMISSION MUST WORK CORRECTLY WITH _OUR_ COPY OF THIS FILE. */
package Project1;
/**
* Each TypeAndSize object represents a sequence of identical sharks, fish,
* or empty cells. TypeAndSizes are your way of telling the test program
* what runs appear in your run-length encoding. TypeAndSizes exist solely
* so that your program can return two integers at once: one representing
* the type (species) of a run, and the other representing the size of a run.
*
* TypeAndSize objects are not appropriate for representing your run-length
* encoding, because they do not represent the degree of hunger of a run of
* sharks.
*
* @author Jonathan Shewchuk
*/
class TypeAndSize {
int type; // runType EMPTY, SHARK, or FISH
int runLength; // Number of cells in the run for that runType.
/**
* Constructor for a TypeAndSize of specified species and run length.
* @param species is Ocean.EMPTY, Ocean.SHARK, or Ocean.FISH.
* @param runLength is the number of identical cells in this run.
* @return the newly constructed Critter.
*/
TypeAndSize(int species, int runLength) {
if ((species != Ocean.EMPTY) && (species != Ocean.SHARK) &&
(species != Ocean.FISH)) {
System.out.println("TypeAndSize Error: Illegal species.");
System.exit(1);
}
if (runLength < 1) {
System.out.println("TypeAndSize Error: runLength must be at least 1.");
System.exit(1);
}
this.type = species;
this.runLength = runLength;
}
}
============================
/* Fish.java */
package Project1;
/**
* The Fish class defines the behavior of a Fish in an Ocean
* @author mohet01
*
*/
class Fish extends Critter{
/**
* Constructor will create a new location for Fish
* @param x
* is the x-coordinate of location(which can be EMPTY) of Fish
* @param y
* is the y-coordinate of location(which can be EMPTY) of Fish
*/
public Fish(int x, int y){
super(x,y);
}
/**
* This method converts the Ocean object of a cell to TypeAndSize object.
*
*/
public TypeAndSize getTypeAndSize(int sameNeighborCount){
TypeAndSize object = new TypeAndSize(Ocean.FISH, sameNeighborCount);
return object;
}
}
==============
解决方案是不完整的,因为
TypeAnSize
类仅包含两个成员type
和runLength
。如果不更改
TypeAndSize
类,我将无法理解如何在hungerLevel
构造函数的以下代码中捕获Shark
的RunLengthEncoding
。if(typeAndSizeObject.type == Ocean.SHARK){
//How do i capture hungerlevel of shark because TypeAndSize only has 2 members
}
我的问题:
请帮我建议一个解决方案,以不修改
hungerLevel
类为约束来捕获每个Shark
对象的TypeAndSize
。注意:这是已经提供的框架代码的link。
最佳答案
正如您所说,这是不可能的。
但是作业也注意到了这一点:
* TypeAndSize objects are not appropriate for representing your run-length
* encoding, because they do not represent the degree of hunger of a run of
* sharks.
http://www.cs.berkeley.edu/~jrs/61bf06/hw/pj1/TypeAndSize.java
结合使用“您不能更改此文件”和“它不适合游程长度编码”使我认为他们希望您提出自己的解决方案。
我想您必须为此解决问题。
我的解决方案?好吧,我想在您的代码中为
Critter
提供一个方法toRunLengthEncodingSegment
,该方法返回“”。代表空,“ F”代表鱼,“ S#”(饥饿时)代表鲨鱼...还有一个抽象工厂,它将像这样从String构建对象:
"."
=空".2"
= 2 x空"F.2F"
=鱼,空,空,鱼"S2,2.FS3"
=鲨鱼(饥饿2),鲨鱼(饥饿2),空,鱼,鲨鱼(饥饿3)这样,您就可以将ocean转换为Strings和将Strings转换为Oceans。这就是RunLengthEncoding的精神。
关于java - 查询有关RunLengthEncoding()构造函数的说明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26756121/