Java:indexOf和put方法 - 我不确定我在这些方法中做错了什么

时间:2015-05-04 22:45:47

标签: java

我不确定为什么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;
 }

}

1 个答案:

答案 0 :(得分:0)

您的代码中存在两个主要问题:

  1. 在课程FastGetListMM中,应对keys列表进行排序。但您没有在keys方法中对put列表进行排序。
  2. 在类SimpleListMM中,put方法假设返回先前与密钥关联的值。但你不是那样做的。