对于link中给出的第III部分,
编写一个RunLengthEncoding构造函数,该构造函数将Ocean对象作为其唯一参数,并将其转换为Ocean的行程编码。要实现这一点,您需要在Ocean类中实现一个sharkFeeding()方法,该方法告诉您给定鲨鱼的饥饿程度。仔细阅读Ocean.java和RunLengthEncoding.java,了解您必须使用哪些方法 写。
Ocean类的字段必须是私有的,因此RunLengthEncoding构造函数将依赖于width(),height(),starveTime(),cellContents()和sharkFeeding()方法。
测试
你的RunLengthEncoding实现需要有一个check()方法, 它遍历游程编码并检查其有效性。 具体来说,如果出现以下任何情况,它应该打印一条警告消息 问题发现:
- 如果连续两次运行的内容类型完全相同。 例如," F12"然后运行" F8"跑是非法的,因为 它们应该合并为一次运行。 (别忘了, 但是,根据他们最近吃过的东西,鲨鱼是分开的。)
- 如果所有游程长度的总和不等于的大小(在单元格中) 海洋;即它的宽度乘以它的高度。
您可能会发现check()方法在帮助您调试时非常有用 第四部分中的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。
答案 0 :(得分:1)
正如你所说,这是不可能的。
但作业也注意到了这一点:
* 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
结合&#34;你不能改变这个文件&#34;用&#34;它不适合游程编码&#34;让我觉得他们希望你提出自己的解决方案。
我想你必须为它做一个解决方法。
我的解决方案?好吧,我在代码中为Critter
提供了一个方法toRunLengthEncodingSegment
,它返回&#34;。&#34;为空,&#34; F&#34;对于鱼类,&#34; S#&#34; (对于鲨鱼来说,#饥饿)...
一个抽象工厂,它将像String一样构建对象:
"."
=空左
".2"
= 2 x空左
"F.2F"
=鱼,空,空,鱼
"S2,2.FS3"
=鲨鱼(饥饿2),鲨鱼(饥饿2),空,鱼,鲨鱼(饥饿3)
像这样,你可以将海洋转换成字符串和字符串到海洋。这就是RunLengthEncoding的精神。