java - 关于 RunLengthEncoding() 构造函数澄清的查询

标签 java oop

对于 link 中给出的第三部分作业,

第三部分:将海洋编码转换为游程编码

write a RunLengthEncoding constructor that takes an Ocean object as its sole parameter and converts it into a run-length encoding of the Ocean. To accomplish this, you will need to implement a sharkFeeding() method in the Ocean class, which tells you how hungry a given shark is. Read Ocean.java and RunLengthEncoding.java carefully for an explanation of what methods you must write.

The fields of the Ocean class MUST be private, so the RunLengthEncoding constructor will rely upon the width(), height(), starveTime(), cellContents(), and sharkFeeding() methods.

Testing

Your RunLengthEncoding implementation is required to have a check() method, which walks through the run-length encoding and checks its validity. Specifically, it should print a warning message if any of the following problems are found:

  • If two consecutive runs have exactly the same type of contents. For instance, an "F12" run followed by an "F8" run is illegal, because they should have been consolidated into a single run. (Don't forget, though, that sharks are divided based on how recently they've eaten.)
  • If the sum of all run lengths doesn't equal the size (in cells) of the Ocean; i.e. its width times its height.

You may find that the check() method is very useful in helping to debug your RunLengthEncoding constructors and addFish() and addShark() in Part IV.

这是不完整的解决方案:

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类(class)仅拥有两名成员 typerunLength

不改变TypeAndSize类,我看不懂,如何捕获hungerLevelSharkRunLengthEncoding 下面的代码中构造函数。

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#”(其中#是饥饿)代表鲨鱼...

还有一个抽象工厂,它将像这样从字符串构建对象:

"." = 空
".2" = 2 x 空
"F.2F" = 鱼、空、空、鱼
"S2,2.FS3" = 鲨鱼(饥饿 2)、鲨鱼(饥饿 2)、空、鱼、鲨鱼(饥饿 3)

像这样,您将能够将海洋转换为字符串,并将字符串转换为海洋。这就是 RunLengthEncoding 的精神。

关于java - 关于 RunLengthEncoding() 构造函数澄清的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26756121/

相关文章:

Java 编程错误 : java. util.ConcurrentModificationException

php - 哎呀,没有选择数据库 php

c# - 创建一个接受多种类型对象的 C# 方法?

c++ - 政策与多态速度

javax.验证.UnexpectedTypeException : No validator could be found for type:

OSX 10.5.8 上 Netbeans 6.8 的 Java 设置以优化 cpu 使用

JAVA如何使用方法打印出main中的数组?

java - 在 AVD 上安装应用程序时出现 Logcat 警告

java - 设计为支持根据对象类型进行请求处理

javascript - 如何从子调用父方法