I'm trying to implement a hashtable using chaining and without any libraries (other than those already in my code), but I'm very stuck. For some reason, the data (100 lines of ints) isn't being added to the list, as seen when it's printed, except for one in the second position (which I assume I need a toString() method for.) Is there any tips or solutions I could get as to how to make this work?
Thanks in advance!
Main + array declaration:
static LinkedList<Node> hashTable[] = new LinkedList[100];
static class Node {
int value;
int key;
}
public static void main(String[] args) throws FileNotFoundException {
File f = new File("Ex5.txt");
Scanner scan = new Scanner(f);
if (f.exists() == false) {
System.out.println("File doesn't exist or could not be found.");
System.exit(0);
}
while (scan.hasNextInt()) {
int n = scan.nextInt();
insert(1, hashFunction(n));
}
for (int i = 0; i < 100; ++i) {
System.out.println(hashTable[i]);
}
}
Insert Function:
public static void insert(int key, int value) {
int index = key % 100;
LinkedList<Node> items = hashTable[index];
if (items == null) {
items = new LinkedList<>();
Node item = new Node();
item.key = key;
item.value = value;
items.add(item);
hashTable[index] = items;
} else {
for (Node item : items) {
if (item.key == key) {
item.value = value;
return;
}
}
Node item = new Node();
item.key = key;
item.value = value;
items.add(item);
}
}
Hashing function:
public static int hashFunction(int value) {
int hashKey = value % 100;
return hashKey;
}
You shall make two changes:
You shall use hashfunction to get the key and keep value as is.
Remove index=key%100 from insert, instead use passed key for
traversing.
Hope this helps.
-------------------------- EDIT --------------------
For printing actual values in linked list, please override toString() method in your Node Class and return a string representation of Key-Value.
Related
i am a CS student in college and i am having trouble with this project where i am supoosed to create a linked list using nodes without importing linked lists, as well as doing a some methods with the list. i am a beginner when it comes to coding, so assume i know nothing, because that is probably the case lol.
import java.io.*;
import java.lang.*;
public class List {
public int listCount = 0;
public char[] linkedList;
public List() throws FileNotFoundException {
}
public List(char[] array) throws FileNotFoundException {
if (array.length == 1) {
Node head = new Node(array[0]);
} else if (array.length > 1) {
Node head = new Node(array[0]);
Node traverse = head;
for (int i = 1; i < array.length; i++) {
while (traverse.nextNode != null) {
traverse = traverse.nextNode;
}
traverse.nextNode = new Node(array[i]);
listCount++;
}
}
}
public List(String w) throws FileNotFoundException {
char[] array2 = new char[w.length()];
for (int i = 0; i < w.length(); i++) {
array2[i] = w.charAt(i);
}
List str = new List(array2);
}
/* Find the character at a index
#param int index
return the character at the chosen index
*/
public char charAt(int index) throws IndexOutOfBoundsException {
char results = linkedList[0];
if (index < linkedList.length && index >= 0) {
results = linkedList[index];
}
return results;
}
public String concat(int index1, int index2) {
return null;
}
/* Determine if the list is empty
return whether the given conditions are true or false
*/
public boolean isEmpty() {
for (int i = 0; i < linkedList.length; i++) {
if (!linkedList.equals(null)) {
System.out.println("This list is not empty");
return false;
}
}
System.out.println("List is empty");
return true;
}
/* Determine the size of the list
return the size of the list
*/
public int size() {
return listCount;
}
/* Create a new String between 2 index's including the start and end index
#param beginIndex is the starting point of the new String
#endIndex is the ending point of new String
return the new String
*/
public String subString(int beginIndex, int endIndex) {
return null;
}
public void insert(Object x) throws IndexOutOfBoundsException {
if (listCount > 100 || listCount < 0) {
throw new IndexOutOfBoundsException("Bag is too large");
} else {
this.linkedList[listCount] = (char) x;
listCount++;
}
}
}
i appreciate any help or pointers ahead of time. we are using a separate node, helper, and driver class as well as a .txt file to assign into my list. i am stuck on the concat and substring methods too, but i want to make sure i am getting the framework correct first. thank you again.
If i understand your question correctly, you are asking how to access a specific type without importing it.
Imports are required to identify which type is referenced when it is used by its simple name. To reference a type without declaring it in the imports you need to use its fully qualified name. For instance
java.util.List<String> someList = new java.util.ArrayList<>();
works without importing List and ArrayList because by declaring the package the class is in it is clear which class is being referenced.
I'll try to do the code later, but here is a book that i found that may help you.
https://cin.ufpe.br/~grm/downloads/Data_Structures_and_Algorithms_in_Java.pdf
I bought a book about DATA STRUCTURE from Pearson company, and it's really a good book, but i don't remember much, it's something like this, that i did in a hurry:
public class List {
private Node head = null;
private Node foot = null;
private Node newNode = null;
private Node auxNode = null;
public List() {
this.head = new Node();
this.foot = new Node();
}
public class Node {
private int adress;
private Node nextNode;
}
public void add(int value) {
this.newNode = new Node();
newNode.adress = value;
if (head == null) {
// Head of the list receive the values of the NEW NODE, so the head of the list
// is not null enymore
head = newNode;
head.nextNode = null;
} else {
// In this case Head is not null
/*The auxiliary node will receive the head and the new Node will become the new Head from the list*/
auxNode = new Node();
auxNode = head;
/*
while(auxNode.nextNode != null ) {
}
auxNode = head;
//head of the list is empty, so we can add the new node
head = newNode;//Here the new node is empty because was transfered to the head
head.nextNode = auxNode; //The head of the list receive the old node that used to be the head
if (head.nextNode == null) {
head.nextNode = newNode;
} else if (head.nextNode != null) {
}*/
}
}
}
```
I hope this help you to get some lead
So I was wondering if there is a way to print out which index of the list has the most collisions? As well as this, I wanted to know, what is the best way to produce a toString() for my LinkedList? I've tried a few times with the default implementation for a LinkedList toString but I can't quite figure out how to do it.
Thanks in advance!
Code:
static LinkedList<Node> hashTable[] = new LinkedList[100];
static class Node {
int value;
int key;
#Override
public String toString() {
return "Value: " + value + " " + "Key: " + key;
}
}
public static void main(String[] args) throws FileNotFoundException {
File f = new File("Ex5.txt");
Scanner scan = new Scanner(f);
if (f.exists() == false) {
System.out.println("File doesn't exist or could not be found.");
System.exit(0);
}
for (int i = 0; i < 100; i++) {
hashTable[i] = null;
}
while (scan.hasNextInt()) {
int n = scan.nextInt();
insert(n, hashFunction(n));
}
for (int i = 0; i < 100; i++) {
System.out.println(hashTable[i]);
}
int emptyEntries = 0;
for (int i = 0; i < 100; i++) {
if (hashTable[i] == null) {
emptyEntries += 1;
}
}
System.out.println("Number of empty entries: " + emptyEntries);
}
public static void insert(int key, int value) {
int index = hashFunction(value);
LinkedList<Node> items = hashTable[index];
if (items == null) {
items = new LinkedList<>();
Node item = new Node();
item.key = key;
item.value = value;
items.add(item);
hashTable[index] = items;
} else {
for (Node item : items) {
if (item.key == key) {
item.value = value;
return;
}
}
Node item = new Node();
item.key = key;
item.value = value;
items.add(item);
}
}
public static int hashFunction(int value) {
int hashKey = value % 100;
return hashKey;
}
Classes are objects. LinkedList is a class. All objects extend java.lang.Object and you can always call Object.toString() on them, but what you are likely looking for is a way to print out all the values. In this case, it is best to use a for loop:
for(int i=0; i<items.size(); i++){
System.out.println(items.get(i));
}
You are printing multiple lines, each containing various amounts of Node objects. You want to find which line has the most amounts of Node objects.
The way to do this is simple. You need nested for loops to print that, and thus you can do this, with your for loops
int maxNodes = Integer.MIN_VALUE;
int index = -1;
for(int i=0; i<LinkedList.size(); i++){
int nodes = 0;
for(int j=0; j<nestedLinkedList.size(); j++){
System.out.print(NodeInformation);
nodes++;
}
if(nodes>maxNodes){
index = i;
maxNodes = nodes;
}
System.out.println();
}
This sample code would find which line would contain the most Node objects.
I'm working on converting a delimited file into an ordered tree structure. Below is a sample input...
1.2.3.4.5
1.3.2.4.5
1.2.4.5.6
I need to be able to convert this into an output like the following (in a searchable tree structure)...
1
-2
--3
---4
----5
--4
---5
----6
-3
--2
---4
----5
My thoughts on a solution to this was to...
Iterate the text file and create an arraylist that represents each row
Use Collections.sort() to make the arraylist sorted
Use a TreeMap to store the "base" record as a key (1 in this case) and an arrayList of strings to contain all the records
Iterate the TreeMap's keys and convert its arrayList to a LinkedHashSet that contains Nodes that represent each entry
Iterate the Tree's keys and print each node buy its index value
I thought everything was working well but when I started testing this approach, I found my output looks like below...
1
-2
--3
---4
----5
--4
---5
----6
-3
--2
As can be seen, the Nodes under 3/2/xx are not present, this is due to the logic I am using to build the LinkedHashSet for my Node values (Node(3, 4)) will simply be ignore because its a duplicate Node. I thought I was going in the right direction with this but now I can see my logic is clearly flawed. Does anyone have any suggestions for an approach for something like this? My current code is below...
TreeBuilder.java
public class TreeBuilder {
public static void main(String[] args) {
// Get a list of records
List<String> data = new ArrayList<String>();
data.add("1.2.3.4.5");
data.add("1.3.2.4.5");
data.add("1.2.4.5.6");
Collections.sort(data);
// Build the "Base" tree
TreeMap<String, List<String>> tree = buildBaseTree(data);
// Build the target tree structure
TreeMap<String, LinkedHashSet<Node>> finalTree = convertListToSet(tree);
printRecords(finalTree);
}
public static void printRecords(
TreeMap<String, LinkedHashSet<Node>> recordTree) {
System.out.println("---------Records---------");
for (Map.Entry<String, LinkedHashSet<Node>> entry : recordTree
.entrySet()) {
System.out.println(entry.getKey());
// Print out the structured data
StringBuilder stringBuilder = new StringBuilder();
Iterator<Node> iterator = entry.getValue().iterator();
while (iterator.hasNext()) {
Node node = iterator.next();
for (int i = 0; i < node.index; i++) {
stringBuilder.append("-");
}
System.out.println(stringBuilder.toString() + node.value);
// "reset" the builder
stringBuilder.setLength(0);
}
}
}
private static TreeMap<String, LinkedHashSet<Node>> convertListToSet(
TreeMap<String, List<String>> tree) {
TreeMap<String, LinkedHashSet<Node>> finalMap = new TreeMap<String, LinkedHashSet<Node>>();
LinkedHashSet<Node> linkedHashSet = new LinkedHashSet<Node>();
// Iterate the entry set
for (Map.Entry<String, List<String>> entry : tree.entrySet()) {
List<String> records = entry.getValue();
for (String record : records) {
String[] recordArray = record.split("\\.");
for (int i = 1; i < recordArray.length; i++) {
Node node = new Node(i, Integer.parseInt(recordArray[i]));
linkedHashSet.add(node);
}
}
finalMap.put(entry.getKey(), linkedHashSet);
// reset our linkedHashSet
linkedHashSet = new LinkedHashSet<Node>();
}
System.out.println("Final map " + finalMap);
return finalMap;
}
/**
* Builds a tree with base record keys and a list of records for each key.
*
* #param data
* #return
*/
private static TreeMap<String, List<String>> buildBaseTree(List<String> data) {
TreeMap<String, List<String>> tree = new TreeMap<String, List<String>>();
List<String> recordList = null;
// First find all base records
for (String record : data) {
String[] baseEntry = record.split("\\.");
if (!tree.containsKey(baseEntry[0])) {
recordList = new ArrayList<String>();
tree.put(baseEntry[0], recordList);
}
}
// Now place all sub-records in each base record
for (String record : data) {
String[] baseEntry = record.split("\\.");
tree.get(baseEntry[0]).add(record);
}
System.out.println("------------------Base Tree---------------");
System.out.println(tree);
System.out.println("------------------------------------------");
return tree;
}
private static List<String> readData(String file) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(new File(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<String> data = new ArrayList<String>();
// Get a list of all the records
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
data.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Sort the list so its ordered
System.out.println("-------------Sorted Data Set-----------");
Collections.sort(data);
for (String record : data) {
System.out.println(record);
}
System.out.println("---------------------------------------");
return data;
}
}
Node.java
public class Node implements Comparable<Node> {
int index;
int value;
public Node(int index, int value) {
this.index = index;
this.value = value;
}
public int getIndex() {
return index;
}
#Override
public String toString() {
return "Node [index=" + index + ", value=" + value + "]";
}
public void setIndex(int index) {
this.index = index;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
#Override
public int compareTo(Node o) {
Node otherNode = (Node) o;
if (this.index > otherNode.index)
return 1;
if (this.index < otherNode.index) {
return -1;
}
return 0;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + index;
result = prime * result + value;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (index != other.index)
return false;
if (value != other.value)
return false;
return true;
}
}
It doesn't have to be complicated. All you need is a SortedMap of SortedMap instances and there's only one trick to it: Parameterizing it recursively for type safety (if desired).
package com.acme;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
List<String> rows = new ArrayList<>();
rows.add("1.2.3.4.5");
rows.add("1.3.2.4.5");
rows.add("1.2.4.5.6");
MyTreeMap root = new MyTreeMap();
for (String row : rows) {
MyTreeMap n = root;
String[] cells = row.split("\\.");
for (String cell : cells) {
MyTreeMap child = n.get(cell);
if (child == null) {
n.put(cell, child = new MyTreeMap());
}
n = child;
}
}
print(root, "", "-");
}
static void print(MyTreeMap m, String indentationStr, String indentationStrAddition) {
for (Entry<String, MyTreeMap> o : m.entrySet()) {
System.out.println(indentationStr + o.getKey());
print(o.getValue(), indentationStr + indentationStrAddition, indentationStrAddition);
}
}
/**
* This is just a construct that helps us to parameterize recursively.
*/
static class MyTreeMap extends TreeMap<String, MyTreeMap> {private static final long serialVersionUID = 1L;}
}
If I understand your problem you want to create search trees from a list of integers that share common prefixes. If that's the case then I think you can achieve this with a lot less code:
private static class TreeNode {
private final Map<Integer, TreeNode> children = new HashMap<>();
public void insert(List<Integer> values) {
if (!values.isEmpty()) {
children.putIfAbsent(values.get(0), new TreeNode());
children.get(values.get(0)).insert(values.subList(1, values.size()));
}
}
public void print(int level) {
for (Map.Entry<Integer, TreeNode> entry : children.entrySet()) {
System.out.print(String.join("", Collections.nCopies(level, "-")));
System.out.println(entry.getKey());
entry.getValue().print(level + 1);
}
}
}
I'm not certain if you intend to sort the list of integers. If so you can add a Collections.sort at the appropriate place in the code.
Okey, so I have some problems with my way of thinking again (this time I'm sick). I need to implement a .txt file into a 2-3 tree wich I have made the foundations of.
My Node class
package kth.id2010.lab.lab04;
public class Node {
boolean isLeaf = false;
int numberOfKeys;
String[] keys = new String[2]; //each node can contain up to 2 keys
int[] key1Values = new int[2]; //every key contains 2 values
int[] key2Values = new int[2]; //every key contains 2 values
Node[] subtrees = new Node[3]; //every node can contain pointers to 3 different nodes
Node[] parent = new Node[1]; //every node contains a pointer to a parent node, if root parent is null
Node(Node n) {
n.numberOfKeys = 0;
n.isLeaf = true;
}
}
My Tree class
package kth.id2010.lab.lab04;
public class Tree {
Node root; // root node of the tree
int n; // number of elements in the tree
private Tree(){
root = new Node(root);
n = 0;
root.parent = null;
}
//Return the values of the key if we find it
public int[] get(Node n, String key){
if(n.isLeaf){
if(n.keys[0].equals(key)){
return(n.key1Values);
}
else if(n.keys[1].equals(key)){
return(n.key2Values);
}
else{
return null;
}
}
else if(key.length() < n.keys[0].length()){
return(get(n.subtrees[0],key));
}
else if(n.numberOfKeys == 2 && key.length() < n.keys[1].length()){
return(get(n.subtrees[1],key));
}
else{
return(get(n.subtrees[2],key));
}
}
//put new values to the key
public void put(Node n, int[] value, String key){
if(n.keys[0].equals(key)){
n.key1Values = value;
}
else if(n.keys[1].equals(key)){
n.key2Values = value;
}
else if(n.keys[0].length() < key.length()){
put(n.subtrees[0],value,key);
}
else if(n.numberOfKeys == 2 && n.keys[1].length() < key.length()){
put(n.subtrees[1],value,key);
}
else{
put(n.subtrees[2],value,key);
}
}
public int size(){
return(this.n);
}
}
And my Driver class
package kth.id2010.lab.lab04;
import edu.princeton.cs.introcs.In;
import java.net.URL;
public class Driver {
public static void main(String[] args) {
URL url = Driver.class.getResource("/kap1.txt");
System.out.println(System.getProperty("user.dir"));
In input = new In(url);
String[] usedWords;
while(!input.isEmpty()){
String line = input.readLine().trim();
String[] words = line.split(" ");
for (String word : words) {
System.out.println(word);
}
}
}
}
So for my assignment each word in words is 1 key, keyValue1[0]is the occurrence number = index in words and keyValue1[1] is the occurrence count. So my thought was that for each word in wordsI add it to a node and add the index number as the first value, and then I add the word to usedWords and check how many times that word is in words. The only thing i'm stuck with is how to add it as a Node and try to sort it, and put the bigger Node that came befor as it´s parent.
public class AdjList {
private Node first; // beginning of list
private int N; // size of lis
private static class Node {
int a;
Node next;
Node(int a, Node next) {
this.a = a;
this.next = next;
}
}
public boolean isEmpty() { return (first == null); }
public int size() { return N; }
public void insert(int a) {
first = new Node(a, first);
N++;
}
public static void main(String[] args) {
AdjList adjlist = new AdjList();
adjlist.insert(1);
adjlist.insert(2);
adjlist.insert(3);
adjlist.insert(4);
System.out.println(adjlist);
}
}
i am trying to write a code on adjacency list using linked list.data items are integers,but it shows error
this is the code i have tried .but it return some other values.can u help me
AdjList#6e1408 is the output
You need two toString() methods, perhaps something like this for the AdjList
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("AdjList [").append(N).append("] = {");
Node n = this.first;
for (int i = 0; i < N; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(n.toString());
n = n.next;
}
sb.append("}");
return sb.toString();
}
Then for your Node you need another one, perhaps something like this
public String toString() {
return String.valueOf(a);
}
I think you will get something more like what you expected if you try those.