Hash Structure in Java issues - java

Here is the HW problem:
At this point, you decide to implement a Hash structure for the contributor data to prepare for searches. You will read the contributor information from a file provided; it is a comma delimited (CSV) file. As each record is read, create a Hash table for the ID field. The limitation for the Hash table is that it has a size of 5, so you need to be able to handle collisions. Collisions should be resolved through the use of a linked list for the ID values (implement this using a stack). Your design should include the following:
A Hash table pointing to a structure for a linked list that contains only the following information:
Each Hash Bucket Collision Item will have the following Information:
ID: Integer; //identifier key for future needs
Hash Bucket Functions/Methods:
Input constructor: //to accept a string for the name and additional information for each contributor (you will only need the ID portion of the input data)
Hash Function constructor: (Hint: You only have 5 Hash buckets, so the function can be a very simple calculation.)
Pop constructor
Push constructor
Print constructor: //to show the contents of a Hash bucket
Deliverables:
A fully documented program to load the Hash table with collisions being handled as a linked list, implemented as a Stack
A test plan to show how the program runs and can be executed
A screenshot showing that the program loaded the data, and after all data is loaded, shows the contents of the first Hash bucket (ideally this is Bucket 0)
I believe I've gotten really close, but I'm used to Python so the Java syntax is something I'm trying to learn. Either way, check the code below to see what I've done.
I believe the problem has to do with the way I am declaring the hash table size. In python, I can just index the array and add a given object to that position in the array. Seems I can't do that in java though. I considered trying a for loop, but it didn't work
I feel like I'm pretty close. Most of the code was given from the professor, but I developed the Stack() class and methods on my own. When I run them they do work, and I got a 100% on that portion.
Through the debugging I've done, I can see that I am initializing an array of size 'size' (in this case 5). However, I can't figure out how to assign a key value pair to a given Stack() index.
Again, I'm used to Python and don't know much java, so I really think it's me not understanding Java syntax.
In python I would just do something along the lines of array[index].append[node]. Then, I could pop the array[index] and display the node one at a time.
import java.util.Scanner;
import java.io.File;
import java.util.regex.Pattern;
public class ContributorManager {
public static void main(String [] args) {
Scanner inputFile = null;
String name = null;
String city = null;
String country = null;
String phone = null;
double contribution = 0;
int id = 0;
Contributor c = null;
Node node = null;
HashTable h = new HashTable(5);
//open contributors file
try {
inputFile = new Scanner(new File("/Users/Dan/Desktop/contributors.csv"));
System.out.println("AsdasdfaDSF");
inputFile.useDelimiter(Pattern.compile("(\\n)|(\\r)|,"));
}
catch (Exception e) {
System.err.println("Error opening file.");
}
//create contributors object for each row, and add to the stack
while (inputFile.hasNext()) {
name = inputFile.next();
city = inputFile.next();
country = inputFile.next();
phone = inputFile.next();
contribution = inputFile.nextDouble();
id = inputFile.nextInt();
inputFile.nextLine(); //advance to the next line
c = new Contributor(name, city, country, phone, contribution, id);
node = new Node(c);
//System.out.println(c.hashFunction());
h.insert(node); //insert node into the hash table
}
h.print(); //print the entire hash table
}
}
public class Contributor {
private String name;
private String city;
private String country;
private String phone;
private double contribution;
private int id;
public Contributor(String name, String city, String country, String phone, double contribution, int id) {
this.name = name;
this.city = city;
this.country = country;
this.phone = phone;
this.contribution = contribution;
this.id = id;
}
public int hashFunction() {
//calculate the hash key value using the id member variable in this object
//the key must always return a value between 0 and 4
int key = this.id % 5;
return key;
//return the hash key value
}
public void printContributor() {
System.out.println("Name: " + name);
System.out.println("City: " + city);
System.out.println("Country: " + country);
System.out.println("Phone: " + phone);
System.out.println("Contribution: " + contribution);
System.out.println("ID: " + id);
System.out.println();
}
}
import java.util.LinkedList;
public class HashTable {
Stack[] table;
private int size;
private int top;
//declaring array
public HashTable(int size) {
//initialize the table array with empty Stack objects
table = new Stack[size];
System.out.println(table.length);
}
public void insert(Node n) {
//determine the hash key of Node n
System.out.println(n);
int key = n.c.hashFunction();
System.out.println(key);
//using the key to determine the table location,
//push Node n onto the stack
System.out.println(table.length);
table[key].push(n);
}
public void print() {
//display the contents of the entire table in order
for (int i=0; i < table.length; i++) {
System.out.println("===== Position " + i + " ======\n");
table[i].print();
System.out.println("========= End ==========");
System.out.println();
}
}
}
public class Node {
Contributor c;
Node next;
public Node(Contributor data){
//initialize member variables
c=data;
next=null;
}
public void displayNode() {
//display the contents of this node
c.printContributor();
}
}
public class Stack {
Node first;
public Stack(){
//initialize the empty stack
first = null;
}
public void push(Node newNode){
//if the stack is empty, make first point to new Node.
if(first==null)
first=newNode;
//if the stack is not empty, loop until we get to the end of the list,
//then make the last Node point to new Node
else
{
first=newNode;
newNode = newNode.next;
}
}
public Node pop() {
//if the stack is empty, return null
if(first==null)
return null;
//Handle the case where there is only one Node in the stack
else if(first.next==null)
{
Node t=first;
return t;
}
//Handle the case where there are at Least two (or more) elements in the stack
else
{
Node t=first;
return t;
}
}
public void print() {
//display the entire stack
Node tempDisplay = first; // start at the beginning of linkedList
while (tempDisplay != null){ // Executes until we don't find end of list.
tempDisplay.displayNode();
tempDisplay = tempDisplay.next;
}
System.out.println();
}
}
contributor.csv
Tim,Murphy,USA,8285557865,200,25
Gordon,Miner,USA,8285551008,150,32
Jean,Bell,USA,8285557503,225,33
Mike,Prather,USA,8285558497,155,34
George ,Pipps,USA,8285557777,100,35

However, I can't figure out how to assign a key value pair to a given Stack() index.
A stack is not an array. Index assignment is not a supported operation, only push and pop from one end of the structure.
It looks like you're having problems with the push and pop operations? Your code comments indicate what needs to be done. if stack is not empty, then loop to the end
You have no loop, and you seem to be inserting into the stack backwards.
Instead you'd probably want something like the following, very similar to the print method
Node n = first;
while (n.next != null) n = n.next;
n.next = newNode;
Similarly for popping, you'd stop the loop when n.next != null && n.next.next == null so that you can set n.next = null and pop it off the list
//TODO: loop logic
Node toPop = n.next;
n.next = null;
return toPop;

Related

How to find an attribute of an object within an Arraylist

I'm trying to use binary search to find the index of the result. However, during the comparison in binary, most of the examples on the internet compare a number in an ArrayList to the input number. But mine one compares the attribute of the object to the input string.
I'm a newbie in coding so I don't have the best word to explain my problem
Here's my code
import java.util.*;
public class Contact{
...attribute, accessor, mutator, tostring, construction...
public static void main(String[] args){
Contact contact1 = new Contact("Adrin", "+19874639110", "adrin#gmail.com");
Contact contact2 = new Contact("April", "+77873093939", "april#gmail.com");
ArrayList<Contact> Contacts = new ArrayList<Contact>();
Contacts.add(contact1);
Contacts.add(contact2);
}
public static int binarySearch(ArrayList<Contact> Contacts, String name){
int left = 0;
int right = Contacts.size() - 1;
while(left<=right){
int middle = (right + left) / 2;
Question for the code below:
????????if(!name.equals(Contacts.get(middle))){???????
right = middle - 1;
}
else if(item > list.get(middle)){
left = middle + 1;
}
else{
return middle;
}
}
return -1;
}
}
Here's is the question I'm struggling:
Create a method search() that takes two parameters : an arraylist of Contacts and name of the person, and returns the index where the person is located in the arraylist. If the person with the given name is not found in the arraylist, the method will return -1. (NOTE: YOU HAVE TO USE BINARY SEARCH ALGORITHM)

How do I insert an object into the correct position using java?

My program has a catalog of objects each with things like titles, item numbers, song artists etc. I need to take the code ive already written and change my addItem method so that it doesnt just put the item on the end of the array but instead places it in the correct spot in the array so that it stays sorted. I am trying to do this by comparing the item type first in alphabetical order(book, movie, or music) and if those are the same i will then compare by item number. I am not sorting the whole array after inserting the object so I know I only need one loop not two nested ones. the only thing is that The only way ive seen of doing this is if the array itself is one of the arguments for the method, so the method header would be something like this.
public static void insertionSort (Comparable[] list)
however I need to do this without changing any of my method headers because if I do id then have to change them in my main method. my add method looks like this right now. the only parameter is the new object that is being added to the array.
public void addItem(Item theItem)
{
items[size] = theItem;
size++;
}
//This Is a class for a general Item
public class Item implements Comparable<Item>
{
// instance variables - replace the example below with your own
private int itemnum;
private String title;
private double price;
/**
* Constructor for objects of class Item
*/
public Item(int id, String t, double p)
{
// initialise instance variables
itemnum = id;
title = t;
price = p;
}
/**
* An example of a method - replace this comment with your own
*
* #param y a sample parameter for a method
* #return the sum of x and y
*/
public int getItemNumber()
{
// put your code here
return itemnum;
}
public String getItemType()
{
return "Item";
}
public String getItemTitle()
{
return title;
}
public String toString()
{
String line1, line2, line3, line4, out;
String itemtype = this.getItemType();
line1 = String.format("Item number: %d%n", itemnum);
line2 = String.format("Item type: %s%n", itemtype);
line3 = String.format("Item title: %s%n", title);
line4 = String.format("Item price: %.2f%n", price);
out = line1 + line2 + line3 + line4 + "\n";
return out;
}
public int compareTo(Item other){
//items are equal
if(this.getItemType().equals(other.getItemType())){
return this.itemnum - other.itemnum;
}
//item types are not equal
else
return this.getItemType().compareTo(other.getItemType());
}
}
How do I make a method to insert an object into an array into the correct position using only the object itself as a parameter?
Did you consider using LinkedList to handle the case? 1st it keeps the data ordered (insertion order by default), 2nd gives you an option to add/remove object at specific index. See below example (extracted from a quick search on Google)
import java.util.*;
public class JavaExample{
public static void main(String args[]){
LinkedList<String> list=new LinkedList<String>();
//Adding elements to the Linked list
list.add("Steve");
list.add("Carl");
list.add("Raj");
//Adding an element to the first position
list.addFirst("Negan");
//Adding an element to the last position
list.addLast("Rick");
//Adding an element to the 3rd position
list.add(2, "Glenn");
//Iterating LinkedList
Iterator<String> iterator=list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}

Arraylist of Objects - How do I remove an entry?

I am doing homework and it states that I have to be able to remove a entry from an arraylist of objects.
I try to check if it contains the user id I want to remove but objects cannot contain strings
public class EmployeeProgramView extends FrameView {
ArrayList <information> database = new ArrayList <information>();
private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
information a;
String ID, firstName, lastName, startDate, annualSalary, linedUp;
ID = idInput.getText();
firstName = firstNameInput.getText();
lastName = lastNameInput.getText();
startDate = startInput.getText();
annualSalary = salaryInput.getText();
linedUp = (firstName+" "+lastName+" "+annualSalary+" "+startDate);
a = new information (ID, firstName, lastName, startDate,annualSalary);
database.add(a);
System.out.println(linedUp);
}
private void listButtonActionPerformed(java.awt.event.ActionEvent evt) {
String temp="";
for (int x=0; x<=database.size()-1; x++) {
temp = temp + database.get(x).ID + " "
+ database.get(x).first + " "
+ database.get(x).last + " "
+ database.get(x).start + " "
+ database.get(x).salary + "\n";
}
finalOutput.setText(temp);
}
private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {
String removeID;
removeID = idInput.getText();
if (database.contains(removeID)){
database.remove(removeID);
} else {
finalOutput.setText("No such ID in database");
}
}
class information{
String ID, first, last, start, salary;
information(String _ID ,String _first, String _last, String _start, String _salary){
ID = _ID;
first = _first;
last = _last;
start = _start;
salary = _salary;
}
}
}
So my question is? How do I remove a object?
The remove method will remove an object from array as long as .equals returns true when comparing that object and the object we are asking to remove. This is true for identical strings; other objects by defaults are only equal to themselves (still, you can add an object to array and retain another variable referring to it).
You can also always remove just by array index.
You may just need to use the method: List < T > #remove, to remove the object in question
Got it!
Thanks everyone for their input. really got my brain thinking different ways haha.
private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {
String temp, removeID;
removeID = idInput.getText();
for (int x = 0; x<=database.size()-1; x++){
temp = database.get(x).ID;
if(removeID.equals(temp)){
database.remove(x);
}
}
}
You have to iterate through the Array and find the ID you are looking for. Just add this into your main class:
public void removeInformation(ArrayList<Information> database, String removeID) {
for(int i = 0; i < database.size(); i++) {
if(database.get(i).getID().equals(removeID)) {
database.remove(database.get(i));
}
}
}
This is unrelated to your question, but by convention classes are named with a capital letter, so your "information" class should be titled "Information".
Also, I just wanted to say that, in case you didn't know, before you type your class you can type import statements. For example:
import java.awt.event.ActionListener;
This way you don't have to type "java.awt.event.ActionListener actionListener" every time you want to use that class.
see basically,
you need to remove an object information from arraylist if the list contains information whose id is same as removeid.
so before removing , you need to do a check for the information id in the list
so go for iterating list and find information in each iteration and check its id equlas to removeid
if equals then do list.remove(information)
for (Information information: database) {
// check for ID is same as remove id
// if equals remove that entire object from list
if (information.ID.equals(removeID)) {
// remove object with ID same as removeid
database.remove(information);
}
}

Linked List object is not storing string input which results in a blank Link list

I am having issues storing data typed in the keyboard to my link list Add method. The point of this program is to implement a queue using a linked list. The only thing is, that the class constructor accepts two parameters for every node in the list (their Name and link).
here is my class file so far...
public class linklist_MP
{
//Private intance variables and links
private linklist_MP front;
private linklist_MP rear;
private linklist_MP link;
private linklist_MP previous;
private String data;
private int count = 0;
private boolean flag;
//Construtor for Each Node's link and parameter type
public linklist_MP(String input, linklist_MP intiallink)
{
data = input;
link = intiallink;
}
public boolean listEmpty()
{
flag = false;
if(count == 0)
{
flag = true;
}
return flag;
}
public void addList(String input)
{
//Creating new node with read input
//linklist_MP node = new linklist_MP(input, null);
if(count == 0)
{
front = new linklist_MP(input, front);
}
else
{
previous = front;
while(previous.link != null)
{
previous = previous.link;
}
rear = previous;
rear.link = new linklist_MP(input, null);
}
count++;
}
public String toString()
{
String result = data + " ";
if (link != null)
{
result += link.toString();
}
return result;
}
}
And Here is my Driver File which makes a object of my class and stores in the user data..
import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;
public class linklistDriver_MP
{
public static void main(String[] args)
{
String input;
Scanner keyboard = new Scanner(System.in);
System.out.println("Just add a String: ");
input = keyboard.nextLine();
linklist_MP object = new linklist_MP(input, null);
object.addList(input);
System.out.println("Add another String: ");
input = keyboard.nextLine();
object.addList(input);
System.out.println("\nTime to print the list out: ");
object.toString();
}
}
Basically when my print method is called in the driver file to print all the nodes in the link list, nothing comes out and the list prints blank. I am trying to figure out why that is since I used the object in my driver to add the two strings the user enters in the keyboard as the add method is called... Thanks in-advance!
The reason your program does not output anything is because you call the method toString() but you never print the output of this method.
However it looks as if your linked list structure is also way off. Essentially a linked list data structure consists of a piece of data and a link to the next node in the sequence.
You however have multiple other nodes linked in your node. You should try to simplify your design because a linked list is a very simple data structure but I think you have overcomplicated it.

Path stack in a Java recursive search

I wrote a simple Depth-First search algorithm, which works, but is failing to build the patch right. Im having a tough time trying to understand, why - so, basically, need your help, guys :)
Here is the code:
public void Search(String from, String to) {
String depart = from;
String destin = to;
if ( (NoChildren(depart) == false)
&& (!depart.equalsIgnoreCase(destin)) ) {
while (!depart.equalsIgnoreCase(to)) {
closeStack.push(depart);
depart = getChildren(depart);
}
}
}
public boolean NoChildren(String from) {
boolean noChildren = false;
int counter = 0;
for(int j = 0; j < Flights.size(); j++) {
FlightInfo flight = (FlightInfo)Flights.elementAt(j);
if (flight.from().equalsIgnoreCase(from)) {
counter++;
}
}
if (counter == 0) {
noChildren = true;
}
return noChildren;
}
public String getChildren(String from) {
for(int j = 0; j < Flights.size(); j++) {
FlightInfo flight = (FlightInfo)Flights.elementAt(j);
if (flight.from().equalsIgnoreCase(from)) {
openStack.push(flight.to().toString());
}
}
return openStack.pop().toString();
}
I made it longer just for clearance, and planning to optimize it - just need to make it work properly first :))
Ok, the main problem is with that closeStack, which was meant to contain a path from start to finish - but now, it contains whatever the algorithm checked :-[
Thanx in advance!!
Maxim, there are a whole bunch of errors in your code. It looks as if you had an idea for what you wanted to do, and then threw some code at it until something emerged and worked a bit, but there's no clear concept here and thus it's no wonder it's not really working.
The core of this program is the Flights collection (why is Flights uppercased?), and it's very possible to build a working route finder around it. I'm not sure whether it would help you more to give you some hints or to simply build the program for you.
Update: I've meanwhile found a flight schedule for a Polish airline (don't ask!) with 203 distinct routings that I can use to fill and test a flight connection structure. I'm going to start hacking and we'll see how it goes.
Update: Here's the code.
To be at all useful for your apparent purpose, it's probably not enough to just find a routing (i.e. an itinerary of airports visited); you probably want a list of flights taken to get there. Note, of course, that there may be multiple combinations of flights that have the same itinerary - this code just finds the first.
You may want to modify the algorithm to place a weight (= cost) on travel time, if you have those, so your passengers get not just the smallest number of legs (= hops from one airport to the next) but also the shortest combined travel time. This more general form of the algorithm would be called Dijkstra's Algorithm, and is also described in Wikipedia.
Interestingly enough, it seems that BFS is not really suited to a recursive solution. Like your original code, my code is essentially imperative with a few loops. Note that the correct "main" data structure for doing BFS is not a stack but a queue!
public class Maxim {
/**
* Create a Maxim instance and run a search on it.
*/
public static void main(String[] args) {
try {
Maxim maxim = new Maxim();
Route r = maxim.findRoute("FCO", "DNV"); // tests a single origin/destination pair
if (r == null) {
System.out.println("No route found");
} else {
System.out.println(Arrays.deepToString(r.toArray()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* A simple Flight. Contains a flight number and only a single leg.
* number: Flight number
* dep: Departure airport
* arr: Arrival airport
*/
class Flight {
final String number, dep, arr;
public Flight(String number, String departure, String arrival) {
this.number = number; this.dep = departure; this.arr = arrival;
}
public String toString() {
return "Flight [number=" + this.number + ", dep=" + this.dep + ", arr=" + this.arr + "]";
}
}
/**
* Airport: A city and a list of Flights originating from it.
*/
class Airport {
public final String city;
public List<Flight> flights = new ArrayList<Flight>();
public Airport(String city) {
this.city = city;
}
public String toString() {
return "Airport [city=" + this.city + ", flights=" + this.flights + "]";
}
}
/**
* Route: A list of flights that get a traveller from a given origin to a destination.
*/
static class Route extends ArrayList<Flight> { }
/**
* Our known list of flights. It's not really needed after initialization.
*/
private List<Flight> flights = new ArrayList<Flight>();
/**
* List of airports. These constitute the graph we search.
*/
private Map<String, Airport> airports = new HashMap<String, Airport>();
/**
* Constructor. Constructs the "airports" graph from a list of "flights" read from a file.
*/
public Maxim() throws Exception {
// Read flights from file into list "flights".
// The file contains strings like " 696KGDWAW" = flight number, departure airport, arrival airport
BufferedReader flightReader = new BufferedReader(new FileReader("/home/carl/XX.flights"));
while (true) {
String flt = flightReader.readLine();
if (flt == null) break;
flights.add(new Flight(flt.substring(0,4), flt.substring(4, 7), flt.substring(7, 10)));
}
flightReader.close();
// Create a map of each airport to a list of Flights departing from it.
// This is the graph we'll be doing BFS on.
for (Flight flight : flights) {
String from = flight.dep;
if (!airports.containsKey(from)) {
Airport port = new Airport(from);
port.flights.add(flight);
airports.put(from, port);
} else {
Airport port = airports.get(from);
port.flights.add(flight);
}
}
}
/**
Algorithm (from Wikipedia):
1. Enqueue the root node.
2. Dequeue a node and examine it.
If the element sought is found in this node, quit the search and return a result.
Otherwise enqueue any successors (the direct child nodes) that have not yet been discovered.
3. If the queue is empty, every node on the graph has been examined – quit the search and return "not found".
4. Repeat from Step 2.
*/
public Route findRoute(String origin, String destination) {
Queue<Airport> queue = new LinkedList<Airport>();
Map<Airport, Flight> backtrack = new HashMap<Airport, Flight>();
Airport oriApt = this.airports.get(origin);
if (oriApt == null) return null; // origin airport not found - no solution
queue.add(oriApt);
while (!queue.isEmpty()) {
Airport apt = queue.remove();
if (apt == null) break;
if (apt.city.equals(destination)) { // Made it to destination; create the route and return it
Route toHere = new Route();
while (apt != oriApt) {
Flight flt = backtrack.get(apt);
toHere.add(flt);
apt = airports.get(flt.dep);
}
Collections.reverse(toHere);
return toHere;
}
// enqueue all new airports reachable from this airport.
// record the flight that got us there in backtrack.
for (Flight flt: apt.flights) {
Airport destApt = airports.get(flt.arr);
if (backtrack.containsKey(destApt)) continue; // we've been to this destination before - ignore
backtrack.put(destApt, flt);
queue.add(destApt);
}
}
// if we're here, we didn't find anything.
return null;
}
}

Categories