我不确定为什么SimpleListMM和FastGetListMM类中的indexOf和put方法不正确。我知道这是错误的,因为代码在某些测试用例中失败了。方法上面的注释解释了它应该做什么。我不能使用Collections.sort方法或实现Comparable或Comparator接口。提前感谢您的帮助!
失败的测试案例:
@Test(timeout=1000) public void fastget_puts_keys_vals_order1(){
IMiniMap<String,Integer> map = new FastGetListMM<String,Integer>();
map.put("Mario",1);
map.put("Luigi",2);
map.put("Peach",3);
map.put("Toad", 4);
assertEquals(al("Luigi","Mario","Peach","Toad"),map.keys());
assertEquals(al(2,1,3,4), map.values());
}
Failure: java.lang.AssertionError: expected:<[Luigi, Mario, Peach, Toad]> but was:<[Mario, Luigi, Peach, Toad]>
@Test(timeout=1000) public void fastget_puts1(){
IMiniMap<String,Integer> map = new FastGetListMM<String,Integer>();
puts1(map);
}
Failure: java.lang.AssertionError:
@Test(timeout=1000) public void simple_puts_keys_vals_order2(){
IMiniMap<Integer,Double> map = new SimpleListMM<Integer,Double>();
int [] ia = { 8, 6, 7, 5, 3, 0, 9,-86,-75,-30,-90};
double[] da = {.6,.07,.50,.33,.00,.90,.86,.75,.30,.90,.08};
for(int i=0; i<ia.length; i++){
assertEquals(null, map.put(ia[i], da[i]));
}
assertEquals(al( 8, 6, 7, 5, 3, 0, 9,-86,-75,-30,-90), map.keys());
assertEquals(al(.6,.07,.50,.33,.00,.90,.86,.75,.30,.90,.08), map.values());
}
Failure: java.lang.AssertionError: expected:<null> but was:<[0.6]>
@Test(timeout=1000) public void fastget_puts_keys_vals_order2(){
IMiniMap<Integer,Double> map = new FastGetListMM<Integer,Double>();
int [] ia = { 8, 6, 7, 5, 3, 0, 9,-86,-75,-30,-90};
double[] da = {.6,.07,.50,.33,.00,.90,.86,.75,.30,.90,.08};
for(int i=0; i<ia.length; i++){
assertEquals(null, map.put(ia[i], da[i]));
}
ArrayList<Integer> expectKeys = al( 8, 6, 7, 5, 3, 0, 9,-86,-75,-30,-90);
Collections.sort(expectKeys);
ArrayList<Double> expectVals = new ArrayList<Double>();
for(Integer k : expectKeys){
for(int i=0; i<ia.length; i++){
if(ia[i] == k){ expectVals.add(da[i]); break; }
}
}
assertEquals(expectKeys, map.keys());
assertEquals(expectVals, map.values());
}
Failure: java.lang.AssertionError: expected:<[-90, -86, -75, -30, 0, 3, 5, 6, 7, 8, 9]> but was:<[8, 6, 7, 5, 3, 0, 9, -86, -75, -30, -90]>
这是抽象类:
import java.util.*;
// A partial list-based implementation of MiniMap. The class and all
// descendants keep parallel lists of keys/values and searches through
// them for IMiniMap operations. All obvious common methods are
// implemented here. Child classes should override the put(key,val)
// and indexOf(key) methods to provide operations for target complexities.
public abstract class AbstractListMM<K,V> implements IMiniMap<K,V>{
protected List <K> keys;
protected List <V> vals;
// Initialize the lists of keys and values with a concrete instance
public AbstractListMM() {
this.keys = new ArrayList<K>();
this.vals = new ArrayList<V>();
}
// Make a (shallow) copy of the keys list and return it
public List<K> keys() {
List<K> newKeys = this.keys;
return newKeys;
}
// Make a (shallow) copy of the vals list and return it
public List<V> values() {
List<V> values = this.vals;
return values;
}
// Find the numeric index of the key as quickly as possible based on
// the type of ListMM being implemented. Return a negative number if
// the given key is not present.
public abstract int indexOf(K key);
// Associate the given key with the given value in the
// lists. Creates an ordering of keys that is compatible with how
// indexOf() works to locate keys.
public abstract V put(K key, V value);
}
这是SimpleListMM类:
import java.util.*;
// A concrete list-based MiniMap which is not optimized for any fast
// operations. The internal key list is not kept in sorted order so
// indexOf() must scan using linear search. put(key,value) may simply
// add new entries to the end of the lists so long as the give key is
// not already present.
public class SimpleListMM<K,V> extends AbstractListMM<K,V>{
// No special parameters required
public SimpleListMM() {
super();
}
// Scan through the list of keys linearly searching for the given
// key. If not present, return a negative number.
//
// TARGET COMPLEXITY: O(N)
// N: Number of key/value associations
public int indexOf(K key) {
for(int i = 0; i < keys.size(); i++) {
if(keys.get(i).equals(key)) {
return i;
}
}
return -1;
}
// Locate the given key and replace its binding with the given
// value. If not present, add the key and value onto the end of
// their respective lists.
//
// TARGET COMPLEXITY: O(N)
// N: Number of key/value associations
@SuppressWarnings("unchecked")
public V put(K key, V value) {
if(keys.contains(key)) {
for(int i = 0; i < keys.size(); i++) {
if(keys.get(i).equals(key)) {
vals.set(keys.indexOf(key), value);
break;
}
}
}
else {
keys.add(key);
vals.add(value);
}
return (V) vals;
}
}
这是FastGetListMM类:
import java.util.*;
// A concrete list-based MiniMap which is optimized for fast get(key)
// operations. The key type must be either Comparable or a Comparator
// must be provided when creating instances. The key list is kept in
// sorted order (via comparable/comparator). Binary search is used on
// the key list to locate the index of the (key,value) pair.
public class FastGetListMM<K,V> extends AbstractListMM<K,V>{
// Comparator used to sort elements; may be null if elements are
// Comparable
public final Comparator<K> cmp;
// Assume elements must be comparable
public FastGetListMM() {
super();
cmp = null;
}
// Use the given comparator to sort the keys
public FastGetListMM(Comparator<K> cmp) {
super();
this.cmp = cmp;
}
// Ensure that the FastGetListMM is set up properly to work with the
// given key; either
//
// 1. key must be an instance of Comparable OR
// 2. The comparator field cmp must not be null.
//
// If both are false, throw a RuntimeException.
public void ensureComparable(K key) {
if(!(key instanceof Comparable) && cmp == null) {
throw new RuntimeException("Not instance of Comparable or comparator object is null");
}
}
// Use binary search to locate where the given key is located. If
// not present, return a negative number. Check to make sure either
// a comparator was used to initialize this instance of
// FastGetListMM or that the keys are Comparable. During binary
// search, use the comparator if present and otherwise rely on the
// keys being comparable.
//
// TARGET COMPLEXITY: O(log N)
// N: Number of key/value associations
@SuppressWarnings("unchecked")
public int indexOf(K key) {
ensureComparable(key);
if (this.cmp == null) {
List<Comparable<K>> comparedKeyResult = (List<Comparable<K>>) this.keys;
return Collections.binarySearch(comparedKeyResult, key, null);
}
else {
return Collections.binarySearch(keys, key, cmp);
}
}
// Locate the given key and replace its binding with the given
// value. If not present, add the key in sorted order into the list
// of keys and add the value at the same location in the list of
// values. Binary search should be used to quickly locate where the
// key should be and replace an existing association. If the key is
// not present, list elements will need to be shifted so this method
// will take longer.
//
// TARGET COMPLEXITY:
// O(log N) if key is already present (use binary search)
// O(N) otherwise as a key may need to be inserted and elements shifted
// N: Number of key/value associations
public V put(K key, V value) {
int posKey;
V putResult = null;
if(indexOf(key) >= 0)
{
posKey = indexOf(key);
resultValue = get(key);
vals.set(posKey, value);
}
else
{
keys.add(key);
vals.add(value);
}
return putResult;
}
}
答案 0 :(得分:0)
您的代码中存在两个主要问题:
FastGetListMM
中,应对keys
列表进行排序。但您没有在keys
方法中对put
列表进行排序。SimpleListMM
中,put
方法假设返回先前与密钥关联的值。但你不是那样做的。