Part5

Set 10

  1. Where is the isValid method specified? Which classes provide an implementation of this method?
    Answer:The isValidmethod is specified by Grid, and is implemented by the BounededGrid class and UnboundedGrid class.
    Source code:

    // @file: GridWorldCode/framework/info/gridworld/grid/Grid.java
    // @line: 50
    boolean isValid(Location loc);
    
    // @file: GridWorldCode/framework/info/gridworld/grid/UnboundedGrid.java
    // @line: 53~56
    public boolean isValid(Location loc)
    {
    	return true;
    }
    
    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 60~64
    
    public boolean isValid(Location loc)
    {
    	return 0 <= loc.getRow() && loc.getRow() < getNumRows()
        	&& 0 <= loc.getCol() && loc.getCol() < getNumCols();
    }
    
  2. Which AbstractGrid methods call the isValid method? Why don’t the other methods need to call it?
    Answer:getValidAdjacentLocations()call the isValid method. Other methods likegetEmptyAdjacentLocations() and getOc​​cupiedAdjacentLocations ,they call getValidAdjacentLocations() insteadly, More Examples like getNeighbors () call getOc​​cupiedAdjacentLocations to invoke getValidAdjacentLocations. They call isValid() indirectly.
    Source code:

    // @file: GridWorldCode/framework/info/gridworld/grid/AbstractGrid.java
    // @line: 44~45
    if (isValid(neighborLoc))
    locs.add(neighborLoc);
    
  3. Which methods of the Grid interface are called in the getNeighbors method? Which classes provide implementations of these methods?
    Answer: getNeighbors()调用了Grid 接口中的get()getOccupiedAdjacentLocations method.
      (1) get() 方法在 BoundedGrid类和UnboundedGrid类中实现。
      (2) getOccupiedAdjacentLocations方法在AbstractGrid类中实现。
    Source code:

    // @file: GridWorldCode/framework/info/gridworld/grid/AbstractGrid.java
    // @line: 31~32
    for (Location neighborLoc : getOccupiedAdjacentLocations(loc))
    neighbors.add(get(neighborLoc));
    
    	// @file: info/gridworld/grid/AbstractGrid.java
    	// @line: 62~71
    	public ArrayList<Location> getOccupiedAdjacentLocations(Location loc)	
    	{
    		ArrayList<Location> locs = new ArrayList<Location>();
    		for (Location neighborLoc : getValidAdjacentLocations(loc))
    		{
    			if (get(neighborLoc) != null)
      				locs.add(neighborLoc);
    		}
    		return locs;
    	}
    
    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 85~91
    public E get(Location loc)
    {
        if (!isValid(loc))
            throw new IllegalArgumentException("Location " + loc
                    + " is not valid");
        return (E) occupantArray[loc.getRow()][loc.getCol()]; // unavoidable warning
    }
    
    // @file: GridWorldCode/framework/info/gridworld/grid/UnboundedGrid.java
    // @line: 66~71
    public E get(Location loc)
    {
        if (loc == null)
            throw new NullPointerException("loc == null");
        return occupantMap.get(loc);
    }
    
  4. Why must the get method, which returns an object of type E, be used in the getEmptyAdjacentLocations method when this method returns locations, not objects of type E?
    Answer:因为get方法返回对存储在网格中给定位置的对象的引用,如果没有对啊ing则返回null,所以get方法必须返回类型E的对象。getEmptyAdjacentLocations方法使用get方法来检测给定位置是否为空,不是空的则将该位置添加到列表中,只有这样我们才能的正确的空的相邻位置。
    Source code:

    // @file: GridWorldCode.framework/info/gridworld/grid/AbstractGrid.java
    // @line: 51~60
    public ArrayList<Location> getEmptyAdjacentLocations(Location loc)
    {
    	ArrayList<Location> locs = new ArrayList<Location>();
    	for (Location neighborLoc : getValidAdjacentLocations(loc))
    	{
    		if (get(neighborLoc) == null)
      		locs.add(neighborLoc);
    	}
    	return locs;
    }
    
  5. What would be the effect of replacing the constant Location.HALF_RIGHT with Location.RIGHT in the two places where it occurs in the getValidAdjacentLocations method?
    Answer:如果用right代替half_right,那么可选择的方向将会减半,也就是从八个变成四个,东南西北。
    Source code:

    // @file: GridWorldCode/framework/info/gridworld/grid/AbstractGrid.java
    // @line: 40~47
    int d = Location.NORTH;
    for (int i = 0; i < Location.FULL_CIRCLE / Location.HALF_RIGHT; i++)
    {
    	Location neighborLoc = loc.getAdjacentLocation(d);
    	if (isValid(neighborLoc))
        	locs.add(neighborLoc);
    	d = d + Location.HALF_RIGHT;
    }
    

Set 11

  1. What ensures that a grid has at least one valid location?
    答:BoundedGrid类的构造函数规定:如果grid的行数或者列数小于或等于0就会抛出异常,这确保了grid中至少有一个有效位置。
    source code:

    //@file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    //@line: 39~46
    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. How is the number of columns in the grid determined by the getNumCols method? What assumption about the grid makes this possible?
    答:因为BoundedGrid是用一个二维数组还储存的,所以调取该二维数组并查询任意一行的长度即可直到grid的列数。
    Grid要求行数和列数至少为一使之成为可能。
    Source Code:

    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 53~58
    public int getNumCols()
    {
    	// Note: according to the constructor precondition, numRows() > 0, so
    	// theGrid[0] is non-null.
    	return occupantArray[0].length;
    }
    
  3. What are the requirements for a Location to be valid in a BoundedGrid?
    答:该 Location所在的行数大于等于0且小于grid的总行数;该 Location所在的列数大于等于0且小于grid的总列数;
    Source Code:

    //@file: GridWroldCode/framework/info/gridworld/grid/BoundedGrid.java
    //@line: 60~64
    public boolean isValid(Location loc)
    {
    	return 0 <= loc.getRow() && loc.getRow() < getNumRows()
    	&& 0 <= loc.getCol() && loc.getCol() < getNumCols();
    }
    

In the next four questions, let r = number of rows, c = number of columns, and n = number of occupied locations.

  1. What type is returned by the getOccupiedLocations method? What is the time complexity (Big-Oh) for this method?
    答:getOccupiedLocations()方法返回的类型是ArrayList<Location>
      因为要得到所有被占用的的位置必须扫描整个网格,所以时间复杂度为O(r*c)
    Source code:

    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 66~83
    public ArrayList<Location> getOccupiedLocations()
    {
    	ArrayList<Location> theLocations = new ArrayList<Location>();
    
    	// Look at all grid locations.
    	for (int r = 0; r < getNumRows(); r++)
    	{
    		for (int c = 0; c < getNumCols(); c++)
    		{
      			// If there's an object at this location, put it in the array.
      			Location loc = new Location(r, c);
      			if (get(loc) != null)
         		theLocations.add(loc);
    		}	
    	}
    
    		return theLocations;
    	}
    
    
  2. What type is returned by the get method? What parameter is needed? What is the time complexity (Big-Oh) for this method?
    答:get()方法返回的类型为E;需要一个Location对象作为参数;复杂度:O(1)
    Source Code:

    // @file: GridWrodlCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 85~91
    public E get(Location loc)
    {
    	if (!isValid(loc))
        throw new IllegalArgumentException("Location " + loc
                                           + " is not valid");
    	return (E) occupantArray[loc.getRow()][loc.getCol()]; // unavoidable warning
    }
    
  3. What conditions may cause an exception to be thrown by the put method? What is the time complexity (Big-Oh) for this method?
    答:当要添加对象的location不在网格内的时候会抛出异常:IllegalArgumentException.
      当要添加的对象是null的话会抛出异常:NullPointerException.
      时间复杂度为:O(1)
    Source Code

    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 93~105
    public E put(Location loc, E obj)
    {
    	if (!isValid(loc))
    		throw new IllegalArgumentException("Location " + loc
                                           + " is not valid");
    	if (obj == null)
        	throw new NullPointerException("obj == null");
    
    	// Add the object to the grid.
    	E oldOccupant = get(loc);
    	occupantArray[loc.getRow()][loc.getCol()] = obj;
    	return oldOccupant;
    }
    
  4. What type is returned by the remove method? What happens when an attempt is made to remove an item from an empty location? What is the time complexity (Big-Oh) for this method?
    答:remove方法返回类型是 E,E可以实类中实际存储的任何对象类型。
      如果该位置在网格内的话并不会报错,如果该位置不在网格内的话就会抛出异常。
      时间复杂度为:O(1)
    Source Code:

    // @file: GridWorldCode/framework/info/gridworld/grid/BoundedGrid.java
    // @line: 107~117
    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;
    }
    
  5. Based on the answers to questions 4, 5, 6, and 7, would you consider this an efficient implementation? Justify your answer.
    答:答:我认为这个实现只能算是一个比较好的实现方式,虽然putgetremove的时间复杂度都是O(1),但是getOc​​cupiedLocations方法的复杂度去到了O(r*c),或许可以使用一些数据结构来存储网格使得该方法的时间复杂度降低。

Set 12

  1. Which method must the Location class implement so that an instance of HashMap can be used for the map? What would be required of the Location class if a TreeMap were used instead? Does Location satisfy these requirements?
    答:Location类必须实现:hashCodeequals方法。
      Location类实现了Comparable接口,所以Location类还必须实现compareTo。此外,TreeMap还要求映射的键是支持相互比较的。
      是的,Location类满足所有要求。
    Source Code:

    // @file: GridWorldCode/framework/info/gridworld/grid/Location.java
    // @line: 28
    public class Location implements Comparable
    
    // @line: 218~221
    public int hashCode()
    {
    	return getRow() * 3737 + getCol();
    }
    
    // @line: 205~212
    public boolean equals(Object other)
    {
    	if (!(other instanceof Location))
    		return false;
    
    Location otherLoc = (Location) other;
    return getRow() == otherLoc.getRow() && getCol() == otherLoc.getCol();
    }
    
  2. Why are the checks for null included in the get, put, and remove methods? Why are no such checks included in the corresponding methods for the BoundedGrid?
    答:因为在UnboundedGrid中,数据存储在HashMap数据结构中,而且任何一个位置在UnbouGrid中都是valid,然而在Map对象中null是合法的键值这与UnboundedGrid中的键值约束冲突,所以在getputremove方法中都得检查以下参数位置是否为空,空则抛出异常。
      在BoundedGrid中,数据存储在二维数组中。在使用位置访问BoundedGrid中的occupantArray方法之前都会先调用isValid方法,一旦位置是null就会直接产生异常,所以在编写其他getputremove方法时并不需要重复实现。

  3. What is the average time complexity (Big-Oh) for the three methods: get, put, and remove? What would it be if a TreeMap were used instead of a HashMap?
    答:getputremove方法的平均时间复杂度时O(1)
      如果使用TreeMap而不是HashMap的话,平均时间复杂度将会提升到O(log n)(n为网格中被占有的的location数量)

  4. How would the behavior of this class differ, aside from time complexity, if a TreeMap were used instead of a HashMap?
    答:因为存储结构的改变会导致返回的对象列表顺序发生变化。存储结构的的变化还会导致数据访问方式的变化。

  5. Could a map implementation be used for a bounded grid? What advantage, if any, would the two-dimensional array implementation that is used by the BoundedGrid class have over a map implementation?
    答:map可以用来实现bounded grid。
      相比于使用map实现,使用二维数组实现的优势:在Bounded grid中如果存储的数据对象很多,几乎占满了整个Bounded Grid的话,使用二维空间会更省内存。因为使用Map不仅要存储数据元素还要存储元素的位置,而二维数组只存储数据元素。

Codeing Exercises Questions

Question 2

These methods could be used without change:

  • public ArrayList<Location> getOccupiedLocations()
  • public E get(Location loc)
  • public E put(Location loc, E obj)
  • public E remove(Location loc)

Fill in the following chart to compare the expected Big-Oh efficiencies for each implementation of the SparseBoundedGrid.

Let r = number of rows, c = number of columns, and n = number of occupied locations

MethodsSparseGridNodeversionLinkedList<OccupantInCol> versionHashMapversionTreeMapversion
getNeighborsO(c)O(c)O(1)O(logn)
getEmptyAdjacentLocationsO(c)O(c)O(1)O(logn)
getOccupiedAdjacentLocationsO(c)O(c)O(1)O(logn)
getOccupiedLocationsO(c+n)O(r+n)O(n)O(n)
getO(c)O(c)O(1)O(logn)
putO(c)O(c)O(1)O(logn)
removeO(c)O(c)O(1)O(logn)

Question 3

  • the Big-Oh efficiency of the get method is :O(1)
  • the efficiency of the put method when the row and column index values are within the current array bounds is O(1)
  • the efficiency when the array needs to be resized : O(n^2), n is the size of the array
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值