Java linked list - issues w 3 methods - java

I am currently working on a linked list project but I am stumped on my last 3 methods, my removeWord(), concatenate() and doubleChar().. I was wondering if anyone one could give me some tips in what I am doing wrong.
class Node {
private char letter;
private Node next;
public Node(char ch, Node link) {
letter = ch;
next = link;
}
public void setLetter(char letter) {
this.letter=letter;
}
public char getLetter() {
return letter;
}
public void setNext(Node next) {
this.next=next;
}
public Node getNext() {
return next;
}
}
class Word {
// instance variable pointing to the head of the linked list
private Node head;
// default constructor
public Word() {
head = null;
}
// copy constructor
public Word(Word w) {
this.head = copy(w.head);
}
private static Node copy(Node l){
Node newL;
if( l ==null){
newL=null;
}else{
newL = new Node(l.getLetter(),copy(l.getNext()));
}
return newL;
}
// constructor from a String
public Word( String s ) {
Node pt;
head = null;
for( int i = s.length()-1; i >=0; i--){
pt = new Node(s.charAt(i),head);
head = pt;
}
}
// for output purposes -- override Object version
// no spaces between the characters, no linefeeds/returns
#Override
public String toString() {
//s.charAt
return toString(head);
// return toString(head);
}
private static String toString(Node L){
String Word="";
if (L == null){
// do nothing
}
else{
Word = L.getLetter() + toString(L.getNext());
// return the letter
}
return Word;
}
// remove the first occurrence of the Word w from this Word
public void removeWord( Word w ) {
head = removeWord(head,w);
}
private static Node removeWord(Node L, Word w)
{
if(L == null)
{
// do nothing
}else if(L==w.head){
L = L.getNext();
}
else {
// remove the word
L.setNext(removeWord(L.getNext(),w));
}
return L;
}
// concatenate a copy of s to the end of this Word
public void concatenate( Word s ) {
this.head = concatenate(head,s);
}
private static Node concatenate(Node L, Word s){
if( L==null){
L = null;
}
else{
L = new Node(L.getLetter(),concatenate(L.getNext(),s));
L.setNext(concatenate(L.getNext(),s));// add to the end of the list
}
return L;
}
// make a copy of every occurrence of ch in this Word
// for example, if this Word is abbcbccb, doubleChar ( 'b' ) should
// change the Word to abbbbcbbccbb
public void doubleChar( char ch ) {
head = doubleChar(head,ch);
}
public static Node doubleChar(Node L, char ch){
if(L == null)
{
}
else if(L.getLetter()==ch){
}
else{
//double
L.setNext(doubleChar(L.getNext(),ch));
}
return L;
}

Related

Wrong Implementation of Binary Search Tree's search Function

I have a Binary Search Tree and I think one of my method is working incorrectly. The program I have is a program that separates the strings read from a file word by word and deletes the special characters in it, then transfers these words to the data structure in alphabetical order. If the same word was previously conveyed during the transmission, it increases the frequency of that word. While checking the output of my program, I saw something like this.
MY OUTPUT:
Readed Line: sun-meal //After some operation it is seperated like "sun" and "metal"
String inserted.
String inserted.
Readed Line: sun-oil //After some operation it is seperated like "sun" and "oil"
String inserted.
String inserted. //Error is here.
TRUE OUTPUT SHOULD BE:
Readed Line: sun-meal //After some operation it is seperated like "sun" and "metal"
String inserted.
String inserted.
Readed Line: sun-oil //After some operation it is seperated like "sun" and "oil"
String inserted.
Repeated String. Frequency +1. //It should be like that.
I will share my source code but what I want to know is what am I doing wrong? Why is "sun" inserted 2 times?
TreeDriver Class:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TreeDriver
{
public static void main(String [] args) throws FileNotFoundException {
Tree stTree = new Tree();
TreeNode compareNode;
Scanner scan = new Scanner(new File(args[0]));
while (scan.hasNextLine()) {
String data = scan.nextLine();
System.out.println("Readed Line: "+data);
String[] convertedData = data.replaceAll("[^a-zA-Z ]", " ").toLowerCase().split("\\s+");
int y = 0;
try {
while(convertedData[y] != null){
String st = convertedData[y];
if (st.contains(" ")) {
}
else{
compareNode = Tree.search(stTree.getRoot(), st);
if (compareNode != null) {
compareNode.upFreq();
System.out.println("\tRepeated String. Frequency +1.");
} else {
stTree.insert(st);
System.out.println("\tString inserted.");
}
y++;
}
}
}
catch(Exception ignored) {
}
}
scan.close();
}
}
TreeNode Class
public class TreeNode
{
private int freq; //frequency of the String in the Node
private String stValue;
private TreeNode left;
private TreeNode right;
public TreeNode(String st)
{
stValue = st;
left = null;
right = null;
freq = 1;
}
public void add(String st)
{
if (left == null)
{
left = new TreeNode(st);
}
else if (right == null)
{
right = new TreeNode(st);
}
else
{
if(countNodes(left) <= countNodes(right))
{
left.add(st);
}
else
{
right.add(st);
}
}
}
//Count the nodes in the binary tree to which root points, and
public static int countNodes( TreeNode root ) {
if ( root == null )
// The tree is empty. It contains no nodes.
return 0;
else {
// Start by counting the root.
int count = 1;
// Add the number of nodes in the left subtree.
count += countNodes(root.getLeft());
// Add the number of nodes in the right subtree.
count += countNodes(root.getRight());
return count; // Return the total.
}
}
public TreeNode getLeft(){
return left;
}
public TreeNode getRight(){
return right;
}
public String getString()
{
return stValue;
}
public void upFreq()
{
freq = freq + 1;
}
public int getFreq()
{
return freq;
}
}
Tree Class:
public class Tree
{
private TreeNode root;
public Tree()
{
root = null;
}
public boolean isEmpty()
{
return root == null;
}
public void insert(String st)
{
if (isEmpty())
{
root = new TreeNode(st);
}
else
{
root.add(st);
}
}
public TreeNode getRoot()
{
return root;
}
public static TreeNode search(TreeNode root, String st)
{
if(root == null)
{
return null;
}
else if(st.equals(root.getString()))
{
return root;
}
else
{ if (root.getLeft() != null)
return search(root.getLeft(), st);
else
return search(root.getRight(), st);
}
}
public TreeNode found(TreeNode root)
{
return root;
}
public static void preorderPrint(TreeNode root)
{
if ( root != null )
{
System.out.print( root.getString() + " " ); // Print the root item.
preorderPrint( root.getLeft() ); // Print items in left subtree.
preorderPrint( root.getRight() ); // Print items in right subtree.
}
}
}
Can you please help me find the problem?
Indeed, your search function is wrong :
if (root.getLeft() != null)
return search(root.getLeft(), st);
else
return search(root.getRight(), st);
You are going through the right child node only if the left one is null, when you should go through both.

finding most frequent element in BST

i have a BST and each node contain a word and a frequencies.
the BST sorted according to the word.
before inserting into the BST we must check if the word in BST or not, if it is not insert it.
if it is there i will increase the frequencies by 1.
the question is
how to get the word which have the highest frequencies?
here is my BST class
public class BST {
private BSTword root;//root as reference variable
// CONSTRUCTORS
public BST() {
root = null;
}
and this is the node which contain the word and its frequencies
public class BSTword {
private int freq;
private String word;
private BSTword left;
private BSTword right;
public BSTword() {
word = "";
left = right = null;
}
public BSTword(String word) {
this.word = word;
freq=1;
left = right = null;
}
and here is what i have done so far
this method in BST class
private BSTword mostCommonWord(BSTword p, int c) {
if (p == null) {//No Subtree
return p;
} else {
if (p != null) {
if (p.getData() == c) {
return p;
}
mostCommonWord(p.getLeft(), c);
if (p.getLeft().getData() > c) {
return p;
}
if (p.getRight().getData() > c) {
mostCommonWord(p.getRight(), c);
}
}
}
return p;
}

About the search()

import java.util.*;
public class ListStack extends LinkedList{
public ListStack() { // <== constructor, different from ListStackComp.java
super();
}
public boolean empty() {
if(isEmpty()){
return true;
}else{
return false;
}
}
public Object push(Object item) {
addToHead(item);
return item;
}
public Object pop() {
Object item = removeFromHead();
return item;
}
public Object peek() {
Object item = get(0);
return item;
}
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 0;i<length;i++){
if(item.equals(current.getData())){
num = i;
}
else{
current = current.getNext();
}
}
return num;
}
}
The result is:
[ 789.123 E Patrick 123 Dog Cat B A ]
peek() returns: 789.123
Patrick is at 7
A is at 7
789.123 is at 7
Peter is at -1
Can help me to solve the problem? Does search() have some error?
class ListNode {
private Object data;
private ListNode next;
ListNode(Object o) { data = o; next = null; }
ListNode(Object o, ListNode nextNode)
{ data = o; next = nextNode; }
public void setData(Object data){
this.data = data;
}
public void setNext(ListNode next){
this.next = next;
}
public Object getData() { return data; }
public ListNode getNext() { return next; }
} // class ListNode
class EmptyListException extends RuntimeException {
public EmptyListException () { super ("List is empty"); }
} // class EmptyListException
class LinkedList {
protected ListNode head; // <== chnage to protected for inheriting
protected ListNode tail; // <== change to protected for inheriting
protected int length; // the length of the list <== chnage to protected for inheriting
public LinkedList() {
head = tail = null;
length = 0;
}
public boolean isEmpty() { return head == null; }
public void addToHead(Object item) {
if (isEmpty())
head = tail = new ListNode(item);
else
head = new ListNode(item, head);
length++;
}
public void addToTail(Object item) {
if (isEmpty())
head = tail = new ListNode(item);
else {
tail.setNext(new ListNode(item));
tail = tail.getNext();
}
length++;
}
public Object removeFromHead() throws EmptyListException {
Object item = null;
if (isEmpty())
throw new EmptyListException();
item = head.getData();
if (head == tail)
head = tail = null;
else
head = head.getNext();
length--;
return item;
}
public Object removeFromTail() throws EmptyListException {
Object item = null;
if (isEmpty())
throw new EmptyListException();
item = tail.getData();
if (head == tail)
head = tail = null;
else {
ListNode current = head;
while (current.getNext() != tail)
current = current.getNext();
tail = current;
current.setNext(null);
}
length--;
return item;
}
public String toString() {
String str = "[ ";
ListNode current = head;
while (current != null) {
str = str + current.getData() + " ";
current = current.getNext();
}
return str + " ]";
}
public int count() {
return length;
}
public Object remove(int n) {
Object item = null;
if (n <= length) { // make sure there is nth node to remove
// special treatment for first and last nodes
if (n == 1) return removeFromHead();
if (n == length) return removeFromTail();
// removal of nth node which has nodes in front and behind
ListNode current = head;
ListNode previous = null;
for (int i = 1; i < n; i++) { // current will point to nth node
previous = current;
current = current.getNext();
}
// data to be returned
item = current.getData();
// remove the node by adjusting two pointers (object reference)
previous.setNext(current.getNext());
}
length--;
return item;
}
public void add(int n, Object item) {
// special treatment for insert as first node
if (n == 1) {
addToHead(item);
return;
}
// special treatment for insert as last node
if (n > length) {
addToTail(item);
return;
}
// locate the n-1th node
ListNode current = head;
for (int i = 1; i < n-1; i++) // current will point to n-1th node
current = current.getNext();
// create new node and insert at nth position
current.setNext(new ListNode(item, current.getNext()));
length++;
}
public Object get(int n) {
// n is too big, no item can be returned
if (length < n) return null;
// locate the nth node
ListNode current = head;
for (int i = 1; i < n; i++)
current = current.getNext();
return current.getData();
}
} // class LinkedList
import java.util.Stack;
import java.util.Iterator;
public class TestStack {
public static void main (String args[]) {
ListStack s = new ListStack();
System.out.println(s);
System.out.println("Patrick is at " + s.search("Patrick"));
s.push(new Character('A'));
System.out.println(s);
s.push(new Character('B'));
System.out.println(s);
s.push("Cat");
System.out.println(s);
s.push("Dog");
System.out.println(s);
s.push(new Integer(123));
System.out.println(s);
s.push("Patrick");
System.out.println(s);
s.push(new Character('E'));
System.out.println(s);
s.push(new Double(789.123));
System.out.println(s);
System.out.println("peek() returns: " + s.peek());
System.out.println("Patrick is at " + s.search("Patrick"));
System.out.println("A is at " + s.search(new Character('A')));
System.out.println("789.123 is at " + s.search(new Double(789.123)));
System.out.println("Peter is at " + s.search("Peter"));
System.out.println();
}
} // class TestStack
There is another code of LinkedList and Test file
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 0;i<length;i++){
if(item.equals(current.getData())){
return i;
}
else{
current = current.getNext();
}
}
return num;
}
Hope It will work.
public Object peek() {
Object item = get(0);
return item;
}
public int search(Object item) {
ListNode current = head;
int num=-1;
for(int i = 1;i<length;i++){
if(item.equals(current.getData())){
num = i;
return num;
}
else{
current = current.getNext();
}
}
return num;
}
There is new problem in the result:
[ A B Cat Dog 123 Patrick E 789.123 ]
peek() returns: A
Patrick is at 6
A is at 1
789.123 is at -1
Peter is at -1
Why the result cannot find 789.123?
The peek() method how can I improve that can find 789.123 is top?

Insert a new string to the trie graph

I am trying to implement the insert method of the Patricia Trie data structure and I am trying to handle this case:
first string: abaxyzalexsky,
second string: abaxyzalex,
third string: abaxyz,
fourth string: aba
I want to mark the trie as the following aba-xyz-alex-sky after inserting the fourth string, but I don't know how can I get it work.
How can I mark the words in the trie in the case above?
public void insert(String s) {
if (nodeRoot == null) {
nodeRoot = new TrieNode(s);
nodeRoot.isWord = true;
} else {
insert(nodeRoot, s);
}
}
private void insert(TrieNode node, String s) {
int len1 = node.edge.length();
int len2 = s.length();
int len = Math.min(len1, len2);
ArrayList<TrieNode> nextNode = node.getNext();
for (int index = 0; index < len; index++) {
if (s.charAt(index) != node.edge.charAt(index)) {
// In case the both words have common substrings and after the
// common substrings the words are split. For example abad, abac
} else if (index == (s.length() - 1)
|| index == (node.edge.length() - 1)) {
// In case the node just needs one path since one word is
// substring of the other.
// For example (aba and abac)
if (len1 > len2) {
// node edge string is longer than the inserted one. For example (abac
// and aba).
String samesubString = node.edge.substring(0, index + 1);
String different = node.edge.substring(index + 1);
node.edge = samesubString;
if (node.getNext() != null && !node.getNext().isEmpty()) {
for (TrieNode subword : node.getNext()) {
//I am here when I insert the third string. The code below retrives wrong data structure.
TrieNode node1 = new TrieNode(different);
node1.isWord = true;
node1.next.add(subword);
node.next.add(node1);
}
} else {
TrieNode leaf = new TrieNode(different);
leaf.isWord = true;
node.next.add(leaf);
for (TrieNode subword : node.getNext()) {
System.out.println(node.getEdge() + "---"
+ subword.getEdge());
}
}
} else {
// new inserted string value is longer. For example (aba
// and abac).
}
} else {
System.out.println("The strings are the same - " + index);
}
}
}
NodeTrie class
package patriciaTrie;
import java.util.ArrayList;
public class TrieNode {
ArrayList<TrieNode> next = new ArrayList<TrieNode>();
String edge;
boolean isWord;
TrieNode(String edge){
this.edge = edge;
}
public ArrayList<TrieNode> getNext() {
return next;
}
public void setNext(ArrayList<TrieNode> next) {
this.next = next;
}
public String getEdge() {
return edge;
}
public void setEdge(String edge) {
this.edge = edge;
}
}

Linked list - Inserting a node before the current node

I'm trying to work on a method that will insert the node passed to it before the current node in a linked list. It has 3 conditions. For this implementation there cannot be any head nodes (only a reference to the first node in the list) and I cannot add any more variables.
If the list is empty, then set the passed node as the first node in the list.
If the current node is at the front of the list. If so, set the passed node's next to the current node and set the first node as the passed node to move it to the front.
If the list is not empty and the current is not at the front, then iterate through the list until a local node is equal to the current node of the list. Then I carry out the same instruction as in 2.
Here is my code.
public class LinkedList
{
private Node currentNode;
private Node firstNode;
private int nodeCount;
public static void main(String[] args)
{
LinkedList test;
String dataTest;
test = new LinkedList();
dataTest = "abcdefghijklmnopqrstuvwxyz";
for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) })); }
System.out.println("[1] "+ test);
for(int i=0; i< dataTest.length(); i++) { test.deleteCurrentNode(); }
System.out.println("[2] "+test);
for(int i=0; i< dataTest.length(); i++)
{
test.insertBeforeCurrentNode(new String(new char[] { dataTest.charAt(i) }));
if(i%2 == 0) { test.first(); } else { test.last(); }
}
System.out.println("[3] "+test);
}
public LinkedList()
{
setListPtr(null);
setCurrent(null);
nodeCount = 0;
}
public boolean atEnd()
{
checkCurrent();
return getCurrent().getNext() == null;
}
public boolean isEmpty()
{
return getListPtr() == null;
}
public void first()
{
setCurrent(getListPtr());
}
public void next()
{
checkCurrent();
if (atEnd()) {throw new InvalidPositionInListException("You are at the end of the list. There is no next node. next().");}
setCurrent(this.currentNode.getNext());
}
public void last()
{
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
while (!atEnd())
{
setCurrent(getCurrent().getNext());
}
}
public Object getData()
{
return getCurrent().getData();
}
public void insertBeforeCurrentNode(Object bcNode) //beforeCurrentNode
{
Node current;
Node hold;
boolean done;
hold = allocateNode();
hold.setData(bcNode);
current = getListPtr();
done = false;
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
}
else if (getCurrent() == getListPtr())
{
System.out.println("hi" + hold);
hold.setNext(getCurrent());
setListPtr(hold);
}
else //if (!isEmpty() && getCurrent() != getListPtr())
{
while (!done && current.getNext() != null)
{
System.out.println("in else if " + hold);
if (current.getNext() == getCurrent())
{
//previous.setNext(hold);
//System.out.println("hi"+ "yo" + " " + getListPtr());
hold.setNext(current.getNext());
current.setNext(hold);
done = true;
}
//previous = current;
current = current.getNext();
}
}
System.out.println(getCurrent());
}
public void insertAfterCurrentNode(Object acNode) //afterCurrentNode
{
Node hold;
hold = allocateNode();
hold.setData(acNode);
if (isEmpty())
{
setListPtr(hold);
setCurrent(hold);
//System.out.println(hold + " hi");
}
else
{
//System.out.println(hold + " hia");
hold.setNext(getCurrent().getNext());
getCurrent().setNext(hold);
}
}
public void insert(Object iNode)
{
insertAfterCurrentNode(iNode);
}
public Object deleteCurrentNode()
{
Object nData;
Node previous;
Node current;
previous = getListPtr();
current = getListPtr();
nData = getCurrent().getData();
if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}
else if (previous == getCurrent())
{
getListPtr().setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
else
{
while (previous.getNext() != getCurrent())
{
previous = current;
current = current.getNext();
}
previous.setNext(getCurrent().getNext());
setCurrent(getCurrent().getNext());
nodeCount = nodeCount - 1;
}
return nData;
}
public Object deleteFirstNode(boolean toDelete)
{
if (toDelete)
{
setListPtr(null);
}
return getListPtr();
}
public Object deleteFirstNode()
{
Object deleteFirst;
deleteFirst = deleteFirstNode(true);
return deleteFirst;
}
public int size()
{
return this.nodeCount;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
private Node allocateNode()
{
Node newNode;
newNode = new Node();
nodeCount = nodeCount + 1;
return newNode;
}
private void deAllocateNode(Node dNode)
{
dNode.setData(null);
}
private Node getListPtr()
{
return this.firstNode;
}
private void setListPtr(Node pNode)
{
this.firstNode = pNode;
}
private Node getCurrent()
{
return this.currentNode;
}
private void setCurrent(Node cNode)
{
this.currentNode = cNode;
}
private void checkCurrent()
{
if (getCurrent() == null) {throw new InvalidPositionInListException("Current node is null and is set to an invalid position within the list! checkCurrent()");}
}
/**NODE CLASS ----------------------------------------------*/
private class Node
{
private Node next; //serves as a reference to the next node
private Object data;
public Node()
{
this.next = null;
this.data = null;
}
public Object getData()
{
return this.data;
}
public void setData(Object obj)
{
this.data = obj;
}
public Node getNext()
{
return this.next;
}
public void setNext(Node nextNode)
{
this.next = nextNode;
}
public String toString()
{
String nodeString;
Node sNode;
sNode = getCurrent();
//System.out.println(nodeCount);
nodeString = ("List contains " + nodeCount + " nodes");
while (sNode != null)
{
nodeString = nodeString + " " +sNode.getData();
sNode = sNode.getNext();
}
return nodeString;
}
}
}
I have it working for my [1] and [2] conditions. But my [3] (that tests insertBeforeCurrentNode()) isn't working correctly. I've set up print statements, and I've determined that my current is reset somewhere, but I can't figure out where and could use some guidance or a solution.
The output for [1] and [2] is correct. The output for [3] should read
[3] List contains 26 nodes: z x v t r p n l j h f d b c e g i k m o q s u w y a
Thanks for any help in advance.
In your toString method you start printing nodes from the currentNode till the end of your list. Because you call test.last() just before printing your results, the currentNode will point on the last node of the list, and your toString() will only print 'a'.
In your toString() method, you may want to change
sNode = getCurrent();
with
sNode = getListPtr();
to print your 26 nodes.
For [3] you need to keep pointers to two nodes: one pointer in the "current" node, the one you're looking for, and the other in the "previous" node, the one just before the current. In that way, when you find the node you're looking in the "current" position, then you can connect the new node after the "previous" and before the "current". In pseudocode, and after making sure that the cases [1] and [2] have been covered before:
Node previous = null;
Node current = first;
while (current != null && current.getValue() != searchedValue) {
previous = current;
current = current.getNext();
}
previous.setNext(newNode);
newNode.setNext(current);

Categories

Resources