zoukankan      html  css  js  c++  java
  • 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啦。

  • 相关阅读:
    Java 上传文件总结
    Java和C# MD5加密比较
    ORM映射框架总结数据操作(七)
    ORM映射框架总结数据操作(五)
    ORM映射框架总结数据操作(一)
    ORM映射框架总结数据操作(四)
    ORM映射框架总结数据操作(六)
    ORM映射框架总结文件下载
    STM32USART DMA_Interrupt例程的学习
    开始STM32的学习
  • 原文地址:https://www.cnblogs.com/lyz1995/p/7241385.html
Copyright © 2011-2022 走看看