查询有关RunLengthEncoding()构造函数的说明

时间:2014-11-05 11:29:20

标签: java oop

对于link中给出的第III部分,

第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课程只包含两名成员typerunLength

在不更改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

1 个答案:

答案 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的精神。