中級實訓

Set 10

1. Where is the isValid method specified? Which classes provide an implementation of this method?

specified : Grid
implementation: BoundedGrid and UnboundedGrid

//@file: framework/info/gridworld/grid/Grid.java
//@line: 50
    boolean isValid(Location loc);

//@file: 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();
    }

//@file: framework/info/gridworld/grid/UnboundedGrid.java
//@line: 53~56
    public boolean isValid(Location loc)
    {
        return true;
    }

2. Which AbstractGrid methods call the isValid method? Why don’t the other methods need to call it?

(1)getValidAdjacentLocations方法調用了isValid方法

//@file: framework/info/gridworld/grid/ AbstractGrid .java
//@line: 44
 if (isValid(neighborLoc))

(2)因爲其他方法(getEmptyAdjacentLocations和getOccupiedAdjacentLocations)通過getValidAdjacentLocations方法間接使用了isVaild方法,所以無需直接調用isVaild方法

//@file: framework/info/gridworld/grid/ AbstractGrid .java
//@line: 54
for (Location neighborLoc : getValidAdjacentLocations(loc))

//@file: framework/info/gridworld/grid/ AbstractGrid .java
//@line: 65
for (Location neighborLoc : getValidAdjacentLocations(loc))

3.Which methods of the Grid interface are called in the getNeighbors method? Which classes provide implementations of these methods?

(1)getNeighbors方法調用了 get 和 getOccupiedAdjacentLocations方法。

//@file: framework/info/gridworld/grid/ AbstractGrid .java
//@line: 28~34
public ArrayList<E> getNeighbors(Location loc)
{
    ArrayList<E> neighbors = new ArrayList<E>();
    for (Location neighborLoc : getOccupiedAdjacentLocations(loc))
        neighbors.add(get(neighborLoc));
    return neighbors;
}

(2)
AbstractGrid 類實現了getOccupiedAdjacentLocations方法,

//@file: framework/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;
}

BoundedGrid and UnboundedGrid 類實現了get方法

//@file: 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: 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?

get方法返回存儲在給定位置的網格中的對象的引用,如果不存在對象,則返回null。getempty鄰接位置調用get方法,並測試結果是否爲空。如果返回null,則該位置爲“空”,並添加到列表中。調用get方法是測試給定位置是否爲空或已佔用的惟一方法。

//@file: 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;
    }

//@file: framework/info/gridworld/grid/Grid.java
//@line: 72~79
/**
 * Returns the object at a given location in this grid. <br />
 * Precondition: <code>loc</code> is valid in this grid
 * @param loc a location in this grid
 * @return the object at location <code>loc</code> (or <code>null<code> 
 *  if the location is unoccupied)
 */
E get(Location loc);

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?

如果附近的位置都是有效的,有效的鄰近位置的數目將從8個減少到4個。
有效的相鄰位置應該是給定位置的北、南、東、西。

如果將Location.HALF_RIGHT替換爲Location.RIGHT值改變後的代碼如下:

//@file: framework/info/gridworld/grid/Location.java
//@line:40
public static final int RIGHT = 90;

//@file: framework/info/gridworld/grid/Location.java
//@line: 48
public static final int HALF_RIGHT = 45;

//@file: framework/info/gridworld/grid/AbstractGrid.java
//@line: 36~49
public ArrayList<Location> getValidAdjacentLocations(Location loc)
 {
        ArrayList<Location> locs = new ArrayList<Location>();

    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.RIGHT;
    }
    return locs;
}

Set 11

1. What ensures that a grid has at least one valid location?

如果rows <= 0或cols <= 0,BoundedGrid的構造函數 BoundedGrid(int rows, int cols)將拋出IllegalArgumentException。

//@file: 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?

(1)occupantArray[0].length

//@file: 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;
}

(2)getNumCols返回佔有者數組第0行中的列數。構造函數確保每個有界網格對象至少有一行和一列。

//@file: 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];
    }

3.What are the requirements for a Location to be valid in a BoundedGrid?

Location 的行數必須大於或等於0且小於BoundedGrid的行數。Location的列數必須大於或等於0,並且小於BoundedGrid的列數。

//@file: 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?

(1) 返回值類型爲ArrayList

(2) 時間複雜度:O(r*c)

//@file: 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?

(1)返回值類型:E
(2)需要的參數:一個Location對象
(3)時間複雜度: O(1)

 //@file: 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?

(1)

  1. 如果要添加的對象的Location不在網gird中(無效Location),則
    拋出IllegalArgumentException。
  2. 如果傳遞給put方法的對象爲null,則拋出NullPointerException。

(2)時間複雜度: O(1)

//@file: 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?

(1)返回值類型:E
(2)沒有異常發生,因爲該方法一律將grid的loc處設爲null。
(3)時間複雜度:O(1)

//@file: 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.

是。
除了getOccupiedLocations方法的時間複雜度爲O(r * c)外,其他方法的時間複雜度均爲O(1).
改進的方法:使用一個鏈表(或者使用 HashMap<Location, E>)存儲occupiedLocations,那麼可以將時間複雜度降爲O(n),n爲occupiedLocations的數目。

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?

(1)Location類必須實現hashCode和equals方法。

//@file: framework/info/gridworld/grid/Location.java
//@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();
}

//@file: framework/info/gridworld/grid/Location.java
//@line: 218~221
public int hashCode()
{
    return getRow() * 3737 + getCol();
}

(2)Location類需要實現compareTo方法

//@file: framework/info/gridworld/grid/Location.java
//@line: 234~246
    public int compareTo(Object other)
    {
        Location otherLoc = (Location) other;
        if (getRow() < otherLoc.getRow())
            return -1;
        if (getRow() > otherLoc.getRow())
            return 1;
        if (getCol() < otherLoc.getCol())
            return -1;
        if (getCol() > otherLoc.getCol())
            return 1;
        return 0;
    }

(3) Location類滿足所有這些需求。

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?

//@file: 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();
    }

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?

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實現。
優點之一是,我們可以節省更多的內存使用二維數組的實現。
因爲我們應該只存儲對象,而散列映射應該存儲位置和對象。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章