Simple HashTable implementation using an array in Java? - java

I'm having a problem with implementing a very simple HashTable using an array. The problem is that the first Item put in the HashTable is always AVAILABLE. Maybe you guys can see what is going wrong. This is the HashTable class:
public class HashTable {
private Item[] data;
private int capacity;
private int size;
private static final Item AVAILABLE = new Item("Available", null);
public HashTable(int capacity) {
this.capacity = capacity;
data = new Item[capacity];
for(int i = 0; i < data.length; i++) {
data[i] = AVAILABLE;
}
size = 0;
}
public int size() {
return size;
}
public int hashThis(String key) {
return key.hashCode() % capacity;
}
public Object get(String key) {
int hash = hashThis(key);
while(data[hash] != AVAILABLE && data[hash].key() != key) {
hash = (hash + 1) % capacity;
}
return data[hash].element();
}
public void put(String key, Object element) {
if(key != null) {
size++;
int hash = hashThis(key);
while(data[hash] != AVAILABLE && data[hash].key() != key) {
hash = (hash + 1) % capacity;
}
data[hash] = new Item(key, element);
}
}
public Object remove(String key) {
// not important now.
throw new UnsupportedOperationException("Can't remove");
}
public String toString() {
String s = "<HashTable[";
for(int i = 0; i < this.size(); i++) {
s += data[i].toString();
if(i < this.size() - 1) {
s += ",";
}
}
s += "]>";
return s;
}
}
For more clarity, this is the Item class:
public class Item {
private String key;
private Object element;
public Item(String key, Object element) {
this.setKey(key);
this.setElement(element);
}
public String key() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object element() {
return element;
}
public void setElement(Object element) {
this.element = element;
}
public String toString() {
String s = "<Item(";
s += this.key() + "," + this.element() + ")>";
return s;
}
}
To give an example:
HashTable ht = new HashTable(10);
ht.put("1", "a");
The output of toString() after putting has to be:
"<HashTable[<Item(1,a)>]>"
but I get:
"<HashTable[<Item(Available,null)>]>"
update: I should probably mention that the next Item gets put correctly and the one after that is not again.

I think the problem is in your toString method. You loop for 0 - size when size = 1 so once so you only print out the first value in your hashTable problem is the first value in your hash table is not a real value it's an AVAILABLE you have to do something like this
EDIT: Sorry I forgot to move the index over.
public String toString() {
String s = "<HashTable[";
int i = 0;
int count = 0;
while(count < this.size()) {
//Skip the AVAILABLE cells
if(data[i] == AVAILABLE) {
i++;
continue;
}
s += data[i].toString();
if(count < this.size() - 1) {
s += ",";
}
count++;
}
s += "]>";
return s;
}

Try this for toString() if still interested in the solution, I ran it and its fine:
public String toString()
{
String s = "<HashTable[";
for (int i = 0; i < this.capacity; i++)
{
if (data[i].Element != null)
{
s += data[i].toString();
if (i < this.size - 1)
{
s += ",";
}
}
}
s += "]>";
return s;
}

Related

B-Tree implementing toString method in Node Class that is giving this error: Cannot invoke forEach((<no type> c) -> {}) on the array type Node<E>[]]

I have Implemented B-Tree, I have given toString to Implement method in Node class as it but its giving errot in this line children.forEach(c ->builder.append(c.toString(depth + 1))); I have tried various methods but not worked
here is other B-Tree files and pdf where is given toString Methods and other Instruction check out these files
toString code
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Node<E extends Comparable<E>> {
public int nodeLocation;
public int index;
private E[] keys = null;
int keysSize = 0;
public Node<E>[] children = null;
public Node<E>[] elements;
int childrenSize = 0;
private Comparator<Node<E>> comparator = new Comparator<Node<E>>() {
#Override
public int compare(Node<E> arg0, Node<E> arg1) {
return arg0.getKey(0).compareTo(arg1.getKey(0));
}
};
protected Node<E> parent = null;
Node(Node<E> parent, int maxKeySize, int maxChildrenSize) {
this.parent = parent;
this.keys = (E[]) new Comparable[maxKeySize + 1];
this.keysSize = 0;
this.children = new Node[maxChildrenSize + 1];
this.childrenSize = 0;
}
E getKey(int index) {
return keys[index];
}
int indexOf(E value) {
for (int i = 0; i < keysSize; i++) {
if (keys[i].equals(value))
return i;
}
return -1;
}
void addKey(E value) {
keys[keysSize++] = value;
Arrays.sort(keys, 0, keysSize);
}
E removeKey(E value) {
E removed = null;
boolean found = false;
if (keysSize == 0)
return null;
for (int i = 0; i < keysSize; i++) {
if (keys[i].equals(value)) {
found = true;
removed = keys[i];
} else if (found) {
// shift the rest of the keys down
keys[i - 1] = keys[i];
}
}
if (found) {
keysSize--;
keys[keysSize] = null;
}
return removed;
}
E removeKey(int index) {
if (index >= keysSize)
return null;
E value = keys[index];
for (int i = index + 1; i < keysSize; i++) {
// shift the rest of the keys down
keys[i - 1] = keys[i];
}
keysSize--;
keys[keysSize] = null;
return value;
}
int numberOfKeys() {
return keysSize;
}
Node<E> getChild(int index) {
if (index >= childrenSize)
return null;
return children[index];
}
int indexOf(Node<E> child) {
for (int i = 0; i < childrenSize; i++) {
if (children[i].equals(child))
return i;
}
return -1;
}
boolean addChild(Node<E> child) {
child.parent = this;
children[childrenSize++] = child;
Arrays.sort(children, 0, childrenSize, comparator);
return true;
}
boolean removeChild(Node<E> child) {
boolean found = false;
if (childrenSize == 0)
return found;
for (int i = 0; i < childrenSize; i++) {
if (children[i].equals(child)) {
found = true;
} else if (found) {
// shift the rest of the keys down
children[i - 1] = children[i];
}
}
if (found) {
childrenSize--;
children[childrenSize] = null;
}
return found;
}
Node<E> removeChild(int index) {
if (index >= childrenSize)
return null;
Node<E> value = children[index];
children[index] = null;
for (int i = index + 1; i < childrenSize; i++) {
// shift the rest of the keys down
children[i - 1] = children[i];
}
childrenSize--;
children[childrenSize] = null;
return value;
}
int numberOfChildren() {
return childrenSize;
}
/**
* {#inheritDoc}
*/
public String toStringg() {
return toString(0);
}
// // based on what toString() does, think about what ‘elements’ and ‘children’
// can be
private String toString(int depth) {
StringBuilder builder = new StringBuilder();
String blankPrefix = new String(new char[depth]).replace("\0", "\t");
List<String> printedElements = new LinkedList<>();
for (Node<E> e : elements)
printedElements.add(e.toString());
String eString = String.join(" :: ", printedElements);
builder.append(blankPrefix).append(eString).append("\n");
children.forEach(c -> builder.append(c.toString(depth + 1))); // this line is giving error
return builder.toString();
}
}
I Have Gievn pdf File where is gievn insructions and code implement I have tried to change childern but not worked I am bound to not make changes in gievn toString method
Arrays in Java doesn't declare their own behavior (don't try to reproduce your experience from languages like JavaScript and TypeScript, where Arrays have methods).
Therefore, you can't invoke method forEach() on the children array (this method is accessible with implementations of Iterable interface, like Collections).
You can use an enhanced for-loop instead:
for (Node<E> node : children) {
builder.append(node.toString(depth + 1));
}
Alternatively, if you declare the property children as a List you'll be able use forEach() with it:
public List<Node<E>> children;
Judging by your assignment requirements, that what you're expected to do.
That would require changing all the methods that make use of children because you can't dial with a List in the same way as with an array. I.e. you would need to use the behavior of the List interface.
children[i] would turn to children.get(i). And children[i] = ... would become children.set(i, ...), or children.add(...).

Java HashSet is allowing duplicates

I need to create an ID based on a 15x15 matrix values and since it is not possible to create an integer of size 15, I tried the following reasoning to create an ID of type double:
First I create a String with the values of the cells and while I do this, I look for the cell that has a value of 0. When I find I enter a dot "." in the String. Then I convert my String to BigDecilmal and the method I call doubleValue ().
public double generateId() {
String sid = "";
for (int i = 0; i < this.matrix[0].length; i++) {
for (int j = 0; j < matrix[1].length; j++) {
if (matrix[i][j].equals("0")) {
sid += ".";
} else {
sid += matrix[i][j];
}
}
}
System.out.println("ID: " + new BigDecimal(sid).doubleValue());
return new BigDecimal(sid).doubleValue();
}
I checked and the generated IDs are uniques.
Based on this, I tried to implement HashCode() as follows:
#Override
public int hashCode() {
long bits = doubleToLongBits(id);
int hash = (int) (bits ^ (bits >>> 32));
System.out.println("hash: " + hash);
return hash;
}
But my HashSet continues with duplicate values :(
Does anyone have a suggestion about how to do this?
~~>EDIT
Sate class:
public class State {
public double id;
public String[][] matrix;
public State() {
}
public State(String[][] matrix) {
this.matrix = createMatrix(matrix);//is created from a existing matrix
this.id = generateId();
}
#Override
public boolean equals(Object other) {
if ((other == null) || !(other instanceof State)) {
return false;
}
return ((State) other).getId().equals(this.getId()) && ((State) other).getId() == this.getId();
}
#Override
public int hashCode() {
long bits = doubleToLongBits(id);
int hash = (int) (bits ^ (bits >>> 32));
System.out.println("hash: " + hash);
return hash;
}
public String toString() {
return "Hashcode: " + this.hashCode();
}
public Double getId() {
return id;
}
public void setId(Double id) {
this.id = id;
}
public String[][] getMatrix() {
return matrix;
}
public void setMatrix(String[][] matrix) {
this.matrix = matrix;
}
public double generateId() {
String sid = "";
for (int i = 0; i < this.matrix[0].length; i++) {
for (int j = 0; j < matrix[1].length; j++) {
if (matrix[i][j].equals("0")) {
sid += ".";
} else {
sid += matrix[i][j];
}
}
}
System.out.println("ID: " + new BigDecimal(sid).doubleValue());
return new BigDecimal(sid).doubleValue();
}
private String[][] createMatrix(String[][] matriz) {
String[][] copia = new String[matriz[0].length][matriz[1].length];
for (int i = 0; i < copia[0].length; i++) {
for (int j = 0; j < copia[1].length; j++) {
copia[i][j] = matriz[i][j];
}
}
return copia;
}
your problem is in the equals method,
you have to remove the last part:
&& ((State) other).getId() == this.getId();
you are checking if the Boolean has the same reference, but they don't need the reference to be equal, it's enough that there value is equal
I would propose using the built-in methods of the Arrays class to generate a hashCode and test for equality:
#Override
public int hashCode() {
return Arrays.deepHashCode(matrix);
}
#Override
public boolean equals(Object other) {
if ((other == null) || !(other instanceof State)) {
return false;
}
State s = (State)other;
return Arrays.deepEquals(matrix, s.matrix);
}

Java HashMap: Changing Bucket Implementation to Linear Probing method

In advance, I apologize for my lack of experience, these are advanced concepts that are difficult to wrap my head around. From what I understand, linear probing is circular, it won't stop until it finds an empty cell.
However I am not sure how to implement it. Some example on how to would be greatly appreciated. Sorry again for the inexperience, I'm not some vetted programmer, I'm picking this up very slowly.
public boolean ContainsElement(V element)
{
for(int i = 0; i < capacity; i++)
{
if(table[i] != null)
{
LinkedList<Entry<K, V>> bucketMethod = table[i];
for(Entry<K, V> entry : bucketMethod)
{
if(entry.getElement().equals(element))
{
return true;
}
}
}
}
return false;
}
Here's a working hash table based on the pseudocode examples found in the Wikipedia article for open addressing.
I think the main differences between the Wikipedia example and mine are:
Treating the hashCode() a little bit due to the way Java does modulo (%) with negative numbers.
Implemented simple resizing logic.
Changed the logic in the remove method a little bit because Java doesn't have goto.
Otherwise, it's more or less just a direct translation.
package mcve;
import java.util.*;
import java.util.stream.*;
public class OAHashTable {
private Entry[] table = new Entry[16]; // Must be >= 4. See findSlot.
private int size = 0;
public int size() {
return size;
}
private int hash(Object key) {
int hashCode = Objects.hashCode(key)
& 0x7F_FF_FF_FF; // <- This is like abs, but it works
// for Integer.MIN_VALUE. We do this
// so that hash(key) % table.length
// is never negative.
return hashCode;
}
private int findSlot(Object key) {
int i = hash(key) % table.length;
// Search until we either find the key, or find an empty slot.
//
// Note: this becomes an infinite loop if the key is not already
// in the table AND every element in the array is occupied.
// With the resizing logic (below), this will only happen
// if the table is smaller than length=4.
while ((table[i] != null) && !Objects.equals(table[i].key, key)) {
i = (i + 1) % table.length;
}
return i;
}
public Object get(Object key) {
int i = findSlot(key);
if (table[i] != null) { // Key is in table.
return table[i].value;
} else { // Key is not in table
return null;
}
}
private boolean tableIsThreeQuartersFull() {
return ((double) size / (double) table.length) >= 0.75;
}
private void resizeTableToTwiceAsLarge() {
Entry[] old = table;
table = new Entry[2 * old.length];
size = 0;
for (Entry e : old) {
if (e != null) {
put(e.key, e.value);
}
}
}
public void put(Object key, Object value) {
int i = findSlot(key);
if (table[i] != null) { // We found our key.
table[i].value = value;
return;
}
if (tableIsThreeQuartersFull()) {
resizeTableToTwiceAsLarge();
i = findSlot(key);
}
table[i] = new Entry(key, value);
++size;
}
public void remove(Object key) {
int i = findSlot(key);
if (table[i] == null) {
return; // Key is not in the table.
}
int j = i;
table[i] = null;
--size;
while (true) {
j = (j + 1) % table.length;
if (table[j] == null) {
break;
}
int k = hash(table[j].key) % table.length;
// Determine if k lies cyclically in (i,j]
// | i.k.j |
// |....j i.k.| or |.k..j i...|
if ( (i<=j) ? ((i<k)&&(k<=j)) : ((i<k)||(k<=j)) ) {
continue;
}
table[i] = table[j];
i = j;
table[i] = null;
}
}
public Stream<Entry> entries() {
return Arrays.stream(table).filter(Objects::nonNull);
}
#Override
public String toString() {
return entries().map(e -> e.key + "=" + e.value)
.collect(Collectors.joining(", ", "{", "}"));
}
public static class Entry {
private Object key;
private Object value;
private Entry(Object key, Object value) {
this.key = key;
this.value = value;
}
public Object getKey() { return key; }
public Object getValue() { return value; }
}
public static void main(String[] args) {
OAHashTable t = new OAHashTable();
t.put("A", 1);
t.put("B", 2);
t.put("C", 3);
System.out.println("size = " + t.size());
System.out.println(t);
t.put("X", 4);
t.put("Y", 5);
t.put("Z", 6);
t.remove("C");
t.remove("B");
t.remove("A");
t.entries().map(e -> e.key)
.map(key -> key + ": " + t.get(key))
.forEach(System.out::println);
}
}
java.util.HashMap implementation of java.util.Map internally provides linear probing that is HashMap can resolve collisions in hash tables.

Heap Iterators java

I have this code for a heap tree and I'm stuck with the iterators.
I need in-order, pre-order and post-order iterators, but I have no idea how to do it.
If someone has an idea or example please help.
class Numbers implements Comparable<Numbers> {
private int value;
public Numbers(int value) {
this.value = value;
}
public String toString() {
return Integer.toString(value);
}
public int getValue() {
return this.value;
}
public int compareTo(Numbers o) {
int tmp = o.getValue();
if (value > tmp)
return 1;
if (value < tmp)
return -1;
return 0;
}
}
class BinaryHeapIsFull extends Exception {
BinaryHeapIsFull() {
super("There is no more place in the heap!");
}
}
public class BinaryHeap<E extends Comparable> {
E[] elements;
int count;
public BinaryHeap(int maxSize) {
elements = (E[]) new Comparable[maxSize];
this.count = 0;
}
public void enqueue(E elem) throws BinaryHeapIsFull {
if (count == elements.length)
throw new BinaryHeapIsFull();
int i = count++;
while (i > 0 && elements[(i - 1) / 2].compareTo(elem) == 1) {
elements[i] = elements[(i - 1) / 2];
i = (i - 1) / 2;
}
elements[i] = elem;
}
public E findMin() {
return elements[0];
}
public E dequeueMin() {
if (count == 0)
return null;
E result = elements[0];
E last = elements[--count];
int i = 0;
while (2 * i + 1 <= count) {
int child = 2 * i + 1;
if (child < count
&& elements[child + 1].compareTo(elements[child]) == -1)
child++;
if (last.compareTo(elements[child]) == -1
|| last.compareTo(elements[child]) == 0)
break;
elements[i] = elements[child];
i = child;
}
elements[i] = last;
return result;
}
public String toString() {
String print = "";
for (int i = 0; i < count; i++)
print += elements[i].toString() + " ";
return print;
}
public void sort() {
int a = count;
for (int i = 0; i < a; i++) {
System.out.print(findMin() + " ");
dequeueMin();
}
}
public static void main(String[] args) throws BinaryHeapIsFull {
BinaryHeap<Numbers> b = new BinaryHeap<Numbers>(10);
b.enqueue(new Numbers(6));
System.out.println(b.toString());
b.enqueue(new Numbers(3));
System.out.println(b.toString());
b.enqueue(new Numbers(4));
System.out.println(b.toString());
b.enqueue(new Numbers(1));
System.out.println(b.toString());
b.enqueue(new Numbers(5));
System.out.println(b.toString());
b.enqueue(new Numbers(0));
System.out.println(b.toString());
b.enqueue(new Numbers(2));
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
System.out.println(b.findMin());
b.sort();
}
}
I'd start with three classes, one for each case, that implements the Iterator interface. Give those iterators an instance of your binary heap and let them do their thing.
public class BinaryHeapPreOrderIterator implements Iterator {
// constructor and methods for Iterator here.
}

Problem in implementing Sorted List by Array in Java

There seems to be a problem in add method of the class I have written.. I want to make a SortedList using an array, but I can't figure out what the problem is. This is my code:
public class SortedList {
private Integer[] elements;
private int size;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
cap = capacity;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el)
{
if(this.isEmpty())
{
elements[0] = el;
size++;
}
else if(this.isFull())
{
this.doubleCapacity();
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
else
{
for(int i = 0; i<this.size(); i++)
{
if(el >= elements[i])
{
elements[i+2] = elements[i+1];
elements[i+1] = el;
}
else
{
elements[i+1] = elements[i];
elements[i] = el;
}
}
size++;
}
}
public String toString()
{
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public static void main(String[] args)
{
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(4);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
}
}
My code works if I only add 2 Integers to my list, but when I try to add the numbers 3,4,5 then I get 3,5,5...
What can be the problem? Thanks..
public class SortedList {
private Integer[] elements;
private int size=0;
private int capacity;
public SortedList(int cap) {
elements = new Integer[cap];
if (cap > 0)
{
capacity = cap;
}
else
capacity = 10;
}
public boolean isEmpty()
{
return size == 0;
}
public boolean isFull()
{
return size == capacity;
}
public int size()
{
return size;
}
public void doubleCapacity()
{
capacity = capacity * 2;
}
public void add(Integer el) throws Exception{
elements[size] = el;
size++;
if(size>capacity){
throw new Exception("Size Exceeded");
}
}
public String toString()
{
sort();
String s = "";
s = s + "<SortedList[";
for(int i = 0; i < this.size(); i++)
{
s = s + elements[i];
if(i < this.size()-1)
s = s + ",";
}
s = s + "]>";
return s;
}
public void sort(){
for (int i=0; i <size()-1; i++) {
if (elements[i] > elements[i+1]) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}
}
public static void main(String[] args)
{
try {
SortedList sl = new SortedList(5);
sl.add(3);
//sl.add(2);
sl.add(6);
sl.add(5);
// sl.add(6);
System.out.println(sl.toString());
} catch (Exception ex) {
Logger.getLogger(SortedList.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Your insertion code doesn't work.
elements[i+1] = elements[i];
elements[i] = el;
What happens to the old value of elements[i+1]?
I'd recommend the following changes to the previous solution. If you're only calling sort in toString(), your list is going to get out of order quickly in cases where you have multiple unsorted elements in a row (Now you could remove sort() from toString()). It's essentially a quick insertion sort that dies as soon as it can't make any more swaps down the list. Again, as dty suggested, a faster choice would be a binary search to find the insertion point.
public void doubleCapacity(){
capacity = capacity * 2;
Integer temp[] = new Integer[capacity];
for (int i = 0; i < size; i++){
temp[i] = elements[i];
}
elements = temp;
}
public void add(Integer el){
if(size+1>capacity){
doubleCapacity();
}
elements[size] = el;
size++;
sort();
}
public void sort(){
//Iterates down the list until it's sorted.
for (int i=size()-2; i >= 0 && (elements[i] < elements[i+1]); i--) {
// exchange elements
int temp = elements[i];
elements[i] = elements[i+1];
elements[i+1] = temp;
}
}

Categories

Resources