Skip to main content

csc_7b_fc/
bimap.rs

1//!  **CSC 123/252 Assignment**
2//!
3//!  This module contains the skeleton of a bijective hashmap that you should
4//!  implement fully.  It is based on the implementation of my version of
5//!  one-way hashmaps found in [crate::hmap].  Consult the documentation
6//!  and source code of [crate::hmap::Hmap] to understand it before proceeding.
7//!  The idea is to use two Hmaps underneath, each mapping a key to the index
8//!  in the other map's underlying vector where the corresponding value is
9//!  stored.  This way a bijective hashmap can be constructed without
10//!  resorting to Copy, Clone, Rc, or anything unsafe.  Click on the
11//!  [Bimap] structure link to see the functions you need to implement.
12//!
13//!  As a challenge, try to also implement an iterator for your structure.
14//!  Try to use the iterator for [Hmap].
15
16#![allow(dead_code, unused_imports, unused_variables)]
17
18use crate::hmap::*;
19use std::hash::{BuildHasher,Hash,Hasher};
20
21//////////////Bimap
22pub struct Bimap<TA,TB> {
23  pub forward : Hmap<TA,usize>,
24  pub backward: Hmap<TB,usize>,
25}
26impl<TA:Hash+Eq, TB:Hash+Eq> Bimap<TA,TB> {
27
28  /// Constructs a new Bimap with default capacity 16.  This function has
29  /// been written for you.
30  pub fn new() -> Self {
31    Bimap {
32      forward : Hmap::new(),
33      backward: Hmap::new(),
34    }
35  }
36
37  /// Constructs a new Bimap with requested capacity.  The actual capacity
38  /// will be the closest power of two that's greater than or equal to the
39  /// requested capacity.  This function has been written for you.
40  pub fn with_capacity(cap:usize) -> Self {
41    Bimap {
42      forward: Hmap::with_capacity(cap),
43      backward: Hmap::with_capacity(cap),
44    }
45  }
46
47  /// Gets the value associated with the key in the forward direction, if
48  /// it exists.  This function has been written for you.
49  pub fn get_forward(&self, key:&TA) -> Option<&TB> {
50    match self.forward.get(key) {
51      Some(vi) => self.backward.table[*vi].as_ref().map(|(v,_)|v),
52      None => None,
53    }
54  }
55
56  /// Complete the implementation of this function
57  pub fn get_backward(&self, key:&TB) -> Option<&TA> {
58    None
59  }
60
61  /// Removes the value associated with the key in the forward direction,
62  /// returning the existing key-value pair, if it exists.  This function
63  /// has been written for you.
64  pub fn remove_forward(&mut self, key:&TA) -> Option<(TA,TB)> {
65    let rf = self.forward.remove(&key);
66    rf.and_then(|(k,vi)|{
67      let mut temp = None;
68      core::mem::swap(&mut temp, &mut self.backward.table[vi]);
69      self.backward.count -= 1;
70      temp.map(|(v,ki)|(k,v))
71    })
72  }
73
74  /// Complete the implementation of this function
75  pub fn remove_backward(&mut self, key:&TB) -> Option<(TA,TB)> {
76    None
77  }  
78
79  /// Complete the implementation of this function.  The general approach is
80  /// the following.  First, call [Bimap::remove_forward] and [Bimap::remove_backward] to
81  /// clear existing values.  Then call [Hmap::find_new_slot]
82  /// to find appropriate places to place the key and values in the forward
83  /// and backward maps.  Then place in the forward map `Some((key,vi))`
84  /// where vi is the index in the backward map where the value
85  /// is found.  And place in the backwards map `Some((val,ki))` where ki
86  /// is the index in the forward map where the key is found.
87  /// Besure to call resize if necessary when adding manually to the forward
88  /// and backwards maps, as well as increase their `count`.
89  ///
90  /// Note that this function returns a pair of options because both the
91  /// key and value could've had prior associations that must be deleted.
92  pub fn set(&mut self, key:TA, val:TB) -> (Option<(TA,TB)>,Option<(TA,TB)>) {
93    (None,None)
94  }
95
96  /// Returns the number of key-value pairs in the bijective map.  This function
97  /// has been written for you, unless you decide to change it.
98  pub fn len(&self) -> usize { self.forward.len() }
99
100}// impl
101
102
103/// Function thesting the implementation - run when finished
104pub fn test() {
105  let mut days = Bimap::new();
106  days.set("Monday",1);
107  days.set("Tuesday",2);
108  days.set("Wednesday",3);
109  days.set("Thursday",4);
110  days.set("Friday",5);
111  days.set("Saturday",6);
112  days.set("Sunday",7);
113  println!("tuesday to 4: {:?}", days.set("Tuesday",4));
114  println!("{:?}",days.get_forward(&"Sunday"));
115  println!("{:?}",days.get_backward(&4));
116  println!("{:?}",days.get_backward(&7));
117  println!("size {}", days.len());
118  /*
119  for (k,v) in days.iter() {
120    println!("{} : {}", k, v);
121  }
122  */
123}
124