cs61b homework6

终于能实现HashTable了!!之前看书一直没搞懂compression那的质数是什么意思,看lecture才明白,对prime求余数可以避免keys的hashcode均可被某一数整除从而造成collision过多的情况(这个概念好难形容啊感觉,具体参见lecture哈),compression算法:((a*hashcode+b)%p)%N,其中p为略大于N的质数。不过a和b我不知道有啥要求没,我是随便取的。

part1:

注意数组内的list要初始化,makeEmpty()后应重新初始化。

HashTableChains代码:

  1 import java.text.DecimalFormat;
  2 import java.util.Random;
  3 
  4 import list.DList;
  5 import list.InvalidNodeException;
  6 import list.List;
  7 import list.ListNode;
  8 
  9 
 10 public class HashTableChained implements Dictionary {
 11     private List[]listarray;
 12     private int size;
 13 
 14   private boolean isPrime(int n){
 15       if(n>2&&n%2==0)
 16           return false;
 17       for(int i=3;i*i<=n;i+=2){
 18           if(n%i==0)
 19               return false;
 20       }
 21       return true;
 22   }
 23 
 24   public HashTableChained(int sizeEstimate) {
 25     while(!isPrime(sizeEstimate)){
 26         sizeEstimate++;
 27     }
 28     listarray=new List[sizeEstimate];
 29     for(int i=0;i<sizeEstimate;i++)
 30         listarray[i]=new DList();
 31   }
 32 
 33  
 34   public HashTableChained() {
 35     listarray=new List[127];
 36     for(int i=0;i<127;i++)
 37         listarray[i]=new DList();
 38   }
 39 
 40 
 41 
 42   int compFunction(int code) {
 43     Random rand=new Random();
 44     int a=7;
 45     int b=13;
 46     int p=listarray.length+1;
 47     while(!isPrime(p))
 48         p++;
 49     int comp=((code*a+b)%p)%(listarray.length-1);
 50     return comp;
 51     
 52   }
 53 
 54 
 55   public int size() {
 56     // Replace the following line with your solution.
 57     return size;
 58   }
 59 
 60   /** 
 61    *  Tests if the dictionary is empty.
 62    *
 63    *  @return true if the dictionary has no entries; false otherwise.
 64    **/
 65 
 66   public boolean isEmpty() {
 67     // Replace the following line with your solution.
 68     return(size==0);
 69   }
 70 
 71 
 72   public Entry insert(Object key, Object value) {
 73     int comp=compFunction(key.hashCode());
 74     Entry entry=new Entry();
 75     entry.key=key;
 76     entry.value=value;
 77     listarray[comp].insertBack(entry);
 78     size++;
 79     return entry;
 80   }
 81 
 82   public Entry find(Object key) {
 83     int comp=compFunction(key.hashCode());
 84     if(listarray[comp]==null||listarray[comp].isEmpty())
 85         return null;
 86     else if(listarray[comp].length()==1)
 87         try {
 88             return ((Entry)(listarray[comp].front().item()));
 89         } catch (InvalidNodeException e) {
 90             e.printStackTrace();
 91             return null;
 92         }
 93     else{
 94         try{
 95         Random rand=new Random();
 96         int r=rand.nextInt(listarray[comp].length());
 97         ListNode node=listarray[comp].front();
 98         for(int i=0;i<r-1;i++)
 99             node=node.next();
100         return (Entry)(node.item());}
101         catch(InvalidNodeException e){
102             e.printStackTrace();
103             return null;
104         }
105     }
106 }
107 
108 
109   public Entry remove(Object key) {
110       int comp=compFunction(key.hashCode());
111         if(listarray[comp]==null||listarray[comp].isEmpty())
112             return null;
113         else if(listarray[comp].length()==1){
114             try {
115                 Entry entry=new Entry();
116                 entry.key=((Entry)(listarray[comp].front().item())).key;
117                 entry.value=((Entry)(listarray[comp].front().item())).value;
118                 listarray[comp].front().remove();
119                 size--;
120                 return entry;
121             } catch (InvalidNodeException e) {
122                 e.printStackTrace();
123                 return null;
124             }   }
125         else{
126             try{
127             Random rand=new Random();
128             int r=rand.nextInt(listarray[comp].length());
129             ListNode node=listarray[comp].front();
130             for(int i=0;i<r-1;i++)
131                 node=node.next();
132             Entry entry=new Entry();
133             entry.key=((Entry)(node.item())).key;
134             entry.value=((Entry)(node.item())).value;
135             node.remove();
136             size--;
137             return entry;
138             }
139             catch(InvalidNodeException e){
140                 e.printStackTrace();
141                 return null;
142             }
143         }
144   }
145 
146   public void makeEmpty() {
147       listarray=new List[listarray.length];
148       for(int i=0;i<listarray.length;i++)
149           listarray[i]=new DList();
150       size=0;
151     // Your solution here.
152   }
153   public void histograph(){
154       double collisions=this.size-listarray.length+listarray.length*Math.pow((1-(double)(1.0/(double)listarray.length)),(double) size);
155       DecimalFormat df=new DecimalFormat("#.00");
156       System.out.println("The expected collisions are: "+df.format(collisions));
157       int count=1;
158       int realCollisions=0;
159       for(int i=0;i<listarray.length;i++){
160           System.out.print("["+listarray[i].length()+"]");
161           if(listarray[i].length()>1)
162               realCollisions+=listarray[i].length()-1;
163           if(count%10==0){
164               System.out.println();
165               count=0;
166           }
167           count++;
168       }
169       System.out.println();
170       System.out.println("The real collisions are: "+realCollisions);
171   }
172 
173 }
View Code

part2:主要是hashcode的算法,按任务上建议的是将每一格点的值化成3进制数的一位,最后内存会存在溢出,所以要强制转换为int。

代码:

      public int hashCode() {
          int b=0;
          for(int i=0;i<DIMENSION;i++){
              for(int j=0;j<DIMENSION;j++){
                  int k=8*i+j;
                  int g=grid[i][j];
                  b+=(int)(g*(int)(3^k));
              }
          }
          return b;
      }

运行结果:每个格子代表该位置存的Entry的个数,collisions和预估的结果还蛮一致。

ps:lab8让设计project2的interface,lab9让证明时间复杂度,都不是编程的task就不打卡了,准备直接开始project2啦。

原文地址:https://www.cnblogs.com/lyz1995/p/7241385.html