Part 5

Part 5
set 10

在GridWorldCode/framework/info/gridworld/grid路径下的grid.java文件中

  1. 在Grid接口中定义,在 BoundedGrid 和 UnboundedGrid类中实现。

  2. getValidAdjacentLocation()方法中直接调用了IsValid()方法,而其它方法如getEmptyAdjacentLocations()方法和getOccupiedAdjacentLocations方法都通过调用getValidAdjacentLocation()方法间接调用了IsValid()方法。

  3. getNeighbors()方法调用了Grid接口中的get() 方法和getOccupiedAdjacentLocations() 方法。BoundedGrid 和 UnboundedGrid类实现了get()方法,而AbstractGrid类实现了getOccupiedAdjacentLocations()方法。

    public ArrayList<E> getNeighbors(Location loc)
    {
         ArrayList<E> neighbors = new ArrayList<E>();
         for (Location neighborLoc : getOccupiedAdjacentLocations(loc))
                neighbors.add(get(neighborLoc));
         return neighbors;
     }
  4. 因为get()方法返回存储在grid中给定位置的引用,如果不存在对象则返回null。而getEmptyAdjacentLocations()方法调用get()方法就是为了判断给定位置是否为空或者是被占用。

  5. getValidAdjacentLocations()方法返回当前位置八个方向上的所有Valid的位置,如果由Location.HALF_RIGHT 变为Location.RIGHT也就是说每次向右旋转45度变为旋转90度,则可以探测到的可以返回的Valid位置会比原来减少一半,只有东、南、西、北四个方向上的Valid位置会被返回。

Set 11

在GridWorldCode/framework/info/gridworld/grid路径下的BoundedGrid.java文件中

  1. 由下面的构造函数可以看出,如果行数或列数小于等于0,会抛出IllegalArgumentException()异常,这保证了grid至少有一个valid位置。

        public BoundedGrid(int rows, int cols)
        {
            if (rows <= 0)
                throw new IllegalArgumentException("rows <= 0");
            if (cols <= 0)
                throw new IllegalArgumentException("cols <= 0");
            occupantArray = new Object[rows][cols];
        }
  2. 因为构造函数保证了grid至少有一个valid位置,即occupantArray[0]一定存在,而返回 occupantArray[0].length就可以确定其它行的列数与occupantArray[0]相同。

    public int getNumCols()
    {
         // Note: according to the constructor precondition, numRows() > 0, so
         // theGrid[0] is non-null.
         return occupantArray[0].length;
    }
  3. 在isValid()方法中定义了一个valid位置的特点:该位置的行、列数都大于0而小于grid的总的行、列数。

        public boolean isValid(Location loc)
        {
            return 0 <= loc.getRow() && loc.getRow() < getNumRows()
                    && 0 <= loc.getCol() && loc.getCol() < getNumCols();
        }
  4. 返回一个包含n个被占用的位置 ArrayList,因为要grid中访问r行、c列的所有位置,复杂度(Big-Oh)为r*c。

  5. 根据在BoundedGrid类中实现的方法get:

    会返回一个E类型,也就是任意可以在occupantArray中存储的类型的值。

    需要一个参数Location。

    (Big-Oh)为1

     public E get(Location loc){
         if (!isValid(loc))
                throw new IllegalArgumentException("Location " + loc
                        + " is not valid");
         return (E) occupantArray[loc.getRow()][loc.getCol()]; 
     }
  6. 根据实现的方法put(Locaion loc,E obj):

    当loc不在grid中或者obj为空时会抛出异常。

    (Big-Oh)为1

    if (!isValid(loc))
        throw new IllegalArgumentException("Location " + loc
                        + " is not valid");
    if (obj == null)
        throw new NullPointerException("obj == null");
  7. 根据实现的方法remove(location loc)

    返回一个E类型的在loc位置存储的grid elements。

    null被存储在相应的位置并返回,并不会抛出异常。

    (Big-Oh)为1

     public E remove(Location loc){
         if (!isValid(loc))
             throw new IllegalArgumentException("Location " + loc
                        + " is not valid");   
            // Remove the object from the grid.
         E r = get(loc);
         occupantArray[loc.getRow()][loc.getCol()] = null;
         return r;
    }
  8. 答案4、5、6、7中提到的四种方法实现只有一个getOccupiedLocations()的复杂度为r*c,其它都为1,可以认为这是一个有效的接口实现。同时获取一个occupantArray二维数组中的元素的的复杂度也是1,因此BoundedGrid类的继承以及接口方法的实现是efficient implementation。

Set 12

在GridWorldCode/framework/info/gridworld/grid路径下的BoundedGrid.java、Location.java文件中

  1. Location类需要实现hashCode()、equals()方法才可以让一个HashMap应用到map。因为当调用equals()方法时,hashCode()方法必须为两个测试为true的位置返回相同的值。Location类实现compareTo()的接口。因此,必须实现compareTo方法才能使Location类成为非抽象类。

    TreeMap要求地图的key值具有可比性,而compareTo()方法实现了key值的比较。

  2. UnboundedGrid类使用HashMap作为数据存储结构来保存grid中的所有元素,所有非null位置都是有效的位置,所以isValid()始终返回true。在Map对象中,null为合法键值,在UnboundedGrid中,null不是有效位置。因此,UnboundGrid方法get、put和remove必须检查location参数,并在参数为null时抛出NullPointerException异常。
    访问BoundedGrid类中的Occupportarray之前调用isValid方法。如果isValid方法中的location参数为null,则尝试访问位置getRow()等方法将导致引发NullPointerException。如果编写的代码在调用get、put和remove方法之前未调用isValid方法,则尝试访问位置getRow这些方法中的()还将导致引发NullPointerException。

//valid函数始终返回true
public boolean isValid(Location loc)
 {
     return true;
 }
 public E get(Location loc)
 {
     if (loc == null)
        throw new NullPointerException("loc == null");
     return occupantMap.get(loc);
 }
  1. 方法get、put和remove的复杂度均为1,所以平均复杂度Big-Oh也为1。

    设n为所有被占用的位置,则平均复杂度将变为O(lg n)。

  2. 大多数情况下,getOccupiedLocations()方法将以不同的顺序返回被占用的位置,HashMap中的键根据使用键的hashcode和size将计算的索引放入哈希表中。遍历键集时访问键的顺序取决于它在哈希表中的位置。树映射将它的键存储在一个平衡的二叉搜索树中,并使用有序遍历遍历遍历该树。将按照Location类实现的的compareTo()方法定义的升序(row major order)访问键集中的键。

  3. map可以在BoundedGrid中实现,如果一个HashMap被应用到BoundedGrid,getOccupiedLocations()方法的平均时间复杂度将是O(n),其中n是网格中的被占用的位置。

    如果BoundedGrid所有的位置都非空,则HashMap需要更多的内存, 因为map保存了每个位置的对像以及location。而二维数组仅仅保存对象,而location通过getRow()、getColum()方法来获取。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值