This question already has answers here:
Explanation of ClassCastException in Java
(12 answers)
Closed 2 years ago.
My professor is having us implement Java comparable interfaces to help my Binary Search Tree compare word objects that hold the word that was scanned and then compare that word to other words, but for whatever reason, the second one I am doing is throwing an error. I do know that the methods he gave us to use does cast (TreeComparable) in it here which I am still not 100% sure why that is the line that the compiler freezes at and gives me the error
java.lang.ClassCastException: class ObjectTreeNode cannot be cast to class
TreeComparable (ObjectTreeNode and TreeComparable are in unnamed module of loader java.net.URLClassLoader
and this is the method that is causing it
public void insertBSTDup(Object o) {
ObjectTreeNode p, q;
ObjectTreeNode r = new ObjectTreeNode(o);
if (root == null)
root = r;
else {
p = root;
q = root;
while (q != null && ((TreeComparable)(r.getInfo())).compareTo(p.getInfo()) != 0) { <---------
p = q;
if (((TreeComparable)(r.getInfo())).compareTo(p.getInfo()) < 0)
q = p.getLeft();
else
q = p.getRight();
}
if (((TreeComparable)(r.getInfo())).compareTo(p.getInfo()) < 0)
setLeftChild(p, r);
else if (((TreeComparable)(r.getInfo())).compareTo(p.getInfo()) > 0)
setRightChild(p, r);
else ((TreeComparable)(p.getInfo())).operate(r.getInfo());
}
}
My Word class is this so far, and the compareTo method is at the bottom, which is implemented in a similar way to the first compareTo I did on my first assignment, and it is comparing word strings so it knows where it will be added.
public class Word implements TreeComparable
{
private String word;
private ObjectList list = new ObjectList();
private ObjectListNode obj;
private int numberOfTimes = 1, LineNumber, position;
public Word(String word, int LineNumber, int position)
{
this.word = word;
this.LineNumber = LineNumber;
this.position = position;
}
public int compareTo(Object o)
{
Word w = (Word) o;
return word.compareTo(w.getWord());
}
public String getWord()
{
return word;
}
and this is the treeComparable method
public interface TreeComparable
{
public int compareTo(Object O);
public void operate(Object O);
public void visit();
}
what can I change to make it so that error to go away, other than remove the treeComparable casting, which I must keep going for this project
Also, this is the objectTreeNode object that the Word object will go into
public class ObjectTreeNode implements ObjectTreeNodeInterface
{
private Object info;
private ObjectTreeNode left;
private ObjectTreeNode right;
public ObjectTreeNode() {
info = null;
left = null;
right = null;
}
public ObjectTreeNode (Object o) {
info = o;
left = null;
right = null;
}
public void setInfo(Object o) {
info = o;
}
public Object getInfo() {
return info;
}
public void setLeft(ObjectTreeNode p) {
left = p;
}
public ObjectTreeNode getLeft() {
return left;
}
public void setRight(ObjectTreeNode p) {
right = p;
}
public ObjectTreeNode getRight() {
return right;
}
}
And here is main
public static void main(String args[]) throws IOException
{
Hash h = new Hash();
Word w;
ObjectBinaryTree bt = new ObjectBinaryTree();
ObjectTreeNode node;
Scanner in = new Scanner(new File("getty.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("csis.txt"));
int numberOfLines = 1;
//h.check();
while(in.hasNext())
{
String word = in.nextLine();
String[] ar = word.split(" ", 0);
System.out.print("\n" + (numberOfLines++) + ": ");
int i = 0;
while(i < ar.length)
{
char check = ar[i].charAt(ar[i].length() - 1);
if(check == ',' || check == '.' || check == '!' || check == '?')
{
ar[i] = ar[i].substring(0, ar[i].length() - 1);
}
w = new Word(ar[i], numberOfLines, (i + 1));
node = new ObjectTreeNode(w);
//System.out.println(ar[i]);
bt.insertBSTDup(node);
System.out.print("(" + (i + 1) + ") " + ar[i] + " ");
i++;
}
}
}
Your insertBSTDup method expects every return value of getInfo to be of type TreeCompareable. It also accepts as input parameter an object which is presumably the object to insert, which therefore should also be a TreeCompareable. In fact you wrap it in an ObjectTreeNode right away:
public void insertBSTDup(Object o) {
ObjectTreeNode p, q;
ObjectTreeNode r = new ObjectTreeNode(o);
However, when you call insertBSTDup you don't pass in a Word object (which would implement TreeComparable but a ObjectTreeNode instead:
node = new ObjectTreeNode(w);
bt.insertBSTDup(node);
So either change the parameter of insertBSTDup to a ObjectTreeNode and get rid of wrapping it again or pass w into insertBSTDup instead of Node.
In a more general sense, much of this could have been avoided if you didn't just take a Object as the parameter, when you really expect a TreeComparable. That way the compiler would have told you that an ObjectTreeNode is not a TreeComparable instead of the problem only occurring at runtime.
Basically every place where you use Object should be TreeComparable instead. And in fact you should probably use a generic type instead, if you already learned of them.
Related
public class BinaryNode<T> {
protected T data;
protected BinaryNode<T> left;
protected BinaryNode<T> right;
public BinaryNode(T element) {
if (element == null)
throw new IllegalArgumentException();
this.data = element;
left = null;
right = null;
}
public int height() {
int leftH = -1, rightH = -1;
if (left != null)
leftH = left.height();
if (right != null)
rightH = right.height();
return Math.max(leftH, rightH) + 1;
}
public int size() {
int leftS = 0, rightS = 0;
if (left != null)
leftS = left.size();
if (right != null)
rightS = right.size();
return leftS + rightS + 1;
}
private String spaces(int count){
String spaces="";
while(count>0){
spaces=spaces+" ";
count=count-1;
}
return spaces;
}
public String toString(){
String str="";
if(left!=null)
str=str+spaces(left.height())+left.toString(); //left
str=str+spaces(left.height()-1)+data.toString()+"\n";//root
if(right!=null)
str=str+spaces(right.height())+right.toString();//right
return str;
}
}
I need to build toString function in BinaryNode class. The method works so that if we print the string it returns we will get one print line per vertex in the tree. In this row, 2*d spaces will appear, where d is the depth of the vertex in the tree and then the information on the vertex will be printed (in the same row).
For example for the following BinarySearchTree (The examples in BinarySearchTree so it will be easier to understand how it needs to print):
BinarySearchTree t4 = new BinarySearchTree(c);
t4.insert(8);
t4.insert(7);
t4.insert(6);
t4.insert(5);
t4.insert(4);
t4.insert(3);
t4.insert(2);
t4.insert(1);
System.out.println("----------t4:----------\n" + t4);
toString need to print:
----------t4:----------
1
2
3
4
5
6
7
8
I wrote above the code that I create but it's doesn't working, the problem is that I know why it doesn't working but I don't know how to fix it.
Basically, I don't know to do it.
Appreciate any help.
Got the solution for those who need it:
private String spaces(int count){
String spaces="";
while(count>0){
spaces=spaces+" ";
count=count-1;
}
return spaces;
}
private String toString(int depth){
String str="";
if(left!=null)
{
str=str+left.toString(depth+1);
}
str=str+spaces(depth)+data.toString()+"\n";
if(right!=null)
{
str=str+right.toString(depth+1);
}
return str;
}
private String toString(String str){
if(left!=null)
str=str+left.toString(" ");
str=str+data.toString()+"\n";
if(right!=null)
str=str+right.toString(" ");
return str;
}
Write a method to find the position of a given element in a stack counting from the top of the stack. More precisely,
the method should return 0 if the element occurs on the top, 1 if there is another element on top of it, and so on. If
the element occurs several times, the topmost position should be returned. If the element doesn’t occur at all, -1
must be returned.
You are asked to write this method in two different ways; one way is to implement it internally inside the
ArrayStack class and the other way is to implement it externally in a separate class. Important: At the end
the stack should be returned to the original state (i.e. no elements should be removed and the order of the elements
should not change).
This is the externall class
public class Stack{
public static int searchstack(ArrayStack z, int n) {
ArrayStack temp = new ArrayStack(z.size());
int c = 0;
boolean flag = false;
while (!z.isEmpty()) {
if (z.top() == n) {
flag = true;
return c;
}
if (z.top() != n) {
temp.push(z.pop());
c++;
flag = false;
}
}
if (flag == false) {
c = -1;
}
while (!temp.isEmpty() && !z.isFull()) {
z.push(temp.pop());
}
return c;
}
public static void main(String[] args) {
ArrayStack z = new ArrayStack(4);
z.push(3); // first element
z.push(7);// 2nd
z.push(8);// 3rd
z.push(1);// 4th
z.printStack();
int n = 3;
System.out.println("Searching externally for" + " " + n + " " + searchstack(z, n));
System.out.println("Searching internally for" +" "+n+" "+ z.searchfor(n)+" "); //THE ERROR IS HERE
}
}
And this is the ArrayClass
public class ArrayStack {
private int[] theStack;
private int maxSize;
private int top;
public ArrayStack(int s) {
maxSize = s;
theStack = new int[maxSize];
top = -1;
}
public void push(int elem) {
top++;
theStack[top] = elem;
}
public int pop() {
int result = theStack[top];
top--;
return result;
}
public int top() {
return theStack[top];
}
public boolean isFull() {
return (top == (maxSize - 1));
}
public boolean isEmpty() {
return (top == -1);
}
public int size() {
return (top + 1);
}
//HERE IS THE METHOD I IMPLEMENTED INTERNALLY AND CALL IT AT THE STACK CLASS
public int searchfor(int n) {
for (int i = top; i >= 0; i--) {
if (theStack[top] == n) {
return i;
}
}
return -1;
}
public void printStack() {
if (top == -1)
System.out.println("Stack is empty!!\n");
else {
System.out.println(theStack[top] + " <- top");
for (int i = top - 1; i >= 0; i--)
System.out.println(theStack[i]);
System.out.println();
}
}
}
The error appearing at the Stack class is at the last line of calling the searchfor method implemented in the Arraystack class , error says that there is no method implemented in Arraystack with the name searchfor (); thiugh I did implement it .whatseems to be the problem ?
You have a bug in your searchStack() implementation. You are losing elements if you find the one you are looking for and it isn't the topmost one.
How to fix your searchStack() method:
keep popping z until you have an empty ArrayStack. While doing so, add the value to a queue.
create valIndex and assign it -1.
Then go through the queue and remove the items from it and adding them to z. While doing so, check for the last occurence of the desired value and save it in valIndex.
if valIndex equals -1 return it. Else, use following equation to convert it to correct index and return:
valIndex = (z.size - 1) - valIndex
I'm trying to implement an inorder, preorder, and postorder traversal algorithm for my BST. It seems that the inorder algorithm is working so far, but it's only returning the first character of the word. I realize that I'm returning char c, but I'm confused on how I would make it return the entire word. Any help would be highly appreciated!
package main;
import java.io.*;
import java.util.*;
// Node class
class Node
{
char c;
boolean end;
Node left, right;
public Node(char c)
{
this.c = c;
this.end = false;
this.left = null;
this.right = null;
}
}
class BinarySearchTree
{
private Node root;
public BinarySearchTree()
{
root = null;
}
public void addValue(String s)
{
root = addValue(root, s, 0);
}
private Node addValue(Node x, String s, int d)
{
char c = s.charAt(d);
if (x == null)
x = new Node(c);
if (c < x.c)
x.left = addValue(x.left, s, d);
else if (c > x.c)
x.right = addValue(x.right, s, d);
else x.end = true;
return x;
}
public boolean search(String s)
{
return search(root, s, 0);
}
private boolean search(Node x, String s, int d)
{
if (x == null)
return false;
char c = s.charAt(d);
if (c < x.c)
return search(x.left, s, d);
else if (c > x.c)
return search(x.right, s, d);
else
return x.end;
}
public void inorder(){
inorder(root);
}
private void inorder(Node r){
if (r != null){
inorder(r.left);
System.out.print(r.c);
inorder(r.right);
}
}
}
public class Project2
{
public static void main(String[] args) throws Exception
{
BinarySearchTree tree = new BinarySearchTree(); // Make new BST object
// Variable for scanned word
String token = "";
// Use scanner for input file
Scanner scan = new Scanner(new File("10words.txt")).useDelimiter("\\s+");
//Check for next line in text file
while (scan.hasNext())
{
token = scan.next();
tree.addValue(token);
}
scan.close();
tree.inorder();
Scanner inputWord = new Scanner(System.in);
System.out.print("\nEnter a word to search: ");
String word = inputWord.next().toLowerCase();
if(tree.search(word) == false){
System.out.println("Word NOT Found!");
} else{
System.out.println("Word Found!");
}
inputWord.close();
}
}
I did not look at your inorder code but you said it works so I'll believe you.
However I did take a look at your addValue code and you only save the first character here. No wonder you can't get the entire word back, you just don't save it :P
Instead, you should change your Node class to accept a String instead of a character. You won't need the d parameter in your addValue method then either.
The Java String class provides the .compareTo () method in order to lexicographically compare Strings. You can use it with string.compareTo(otherString)
This method will return a value < 0, equal to 0 or > 0.
< 0 means string is lexicographically smaller than otherString (for example: "Apple" would be smaller than "Banana")
= 0 means it's the exact same word
> 0 means string is bigger than otherString (for example: "Banana" would be bigger than "Apple")
your addValue method looks like it is incorrect. it only modifies the root, then character will be equal, so it returns. In particular d is never modified.
On a more fondamental level, a BST would be appropriate to look for a character in a tree, not for looking for a String. If you want to look for a word, you can use a Trie instead (which is not a binary tree).
I'm writing a program that asks the user for a postfix expression, and then outputs the result to the expression. I am attempting to do this using a Singly Linked List, and using the Adapter Pattern to create a stack.
The code for the SinglyLinkedList class, the LinkedStack class, and the Stack implementation are all straight out of a Data Structures book that I own. So the SinglyLinkedListTest class is the only one that has my own code in it (and has errors).
I've written a program that simply uses a stack to evaluate a postfix expression before, but I'm getting confused this time with the extra classes included.
I'm sure I have a ton of errors, but the most obvious ones to me are in my SinglyLinkedListTest class, every time I push a value onto the stack. I know the issue is that I am attempting to push Objects and characters onto the stack instead of the arguments that match push(E e), but I don't know how to alter my code to make this work.
Any suggestions or input would be greatly appreciated.
Here is my Stack Implementation:
package PostFix;
public interface Stack<E>
{
int size();
boolean isEmpty();
void push(E e);
E pop();
}
Here is my LinkedStack class:
package PostFix;
public class LinkedStack <E> implements Stack<E>
{
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
public LinkedStack()
{
}
public int size()
{
return list.size();
}
public boolean isEmpty()
{
return list.isEmpty();
}
public void push(E e)
{
list.addFirst(e);
}
public E pop()
{
return list.removeFirst();
}
}
Here is my SinglyLinkedList class:
package PostFix;
public class SinglyLinkedList<E>
{
private static class Node<E>
{
private E element;
private Node<E> next;
public Node(E e, Node<E> n)
{
element = e;
next = n;
}
public E getElement()
{
return element;
}
public Node<E> getNext()
{
return next;
}
}
private Node<E> head = null;
private Node<E> tail = null;
private int size = 0;
public SinglyLinkedList()
{
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size == 0;
}
public void addFirst(E e)
{
head = new Node<>(e, head);
if (size == 0)
{
tail = head;
}
size++;
}
public E removeFirst()
{
if (isEmpty())
{
return null;
}
E answer = head.getElement();
head = head.getNext();
size--;
if (size == 0)
{
tail = null;
}
return answer;
}
}
Here is my final SinglyLinkedListTest class:
package PostFix;
import java.util.Scanner;
public class SinglyLinkedListTest
{
public static void main(String[] args)
{
Double num1, num2, answer;
char c;
Stack<Double> stack = new LinkedStack<>();
Scanner input = new Scanner(System.in);
System.out.println("Enter the expression you would like to evaluate: ");
String someString = input.nextLine();
for (int index = 0; index < someString.length(); index++)
{
c = someString.charAt(index);
if (Character.isDigit(c))
{
stack.push((double)Character.digit(c, 10));
}
else if (c == '+')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1+num2;
stack.push(answer);
}
else if (c == '-')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1-num2;
stack.push(answer);
}
else if (c == '*')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1*num2;
stack.push(answer);
}
else if (c == '/')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1/num2;
stack.push(answer);
}
}
System.out.println("The result is: " + stack.pop());
}
}
Stack<String> buffer = new LinkedStack<>();
Poor name: call it stack.
You've declared it as Stack<String> but you're pushing chars:
buffer.push(someString.charAt(index));
and Objects:
buffer.push(answer);
and popping ints:
num1 = buffer.pop();
You are never either pushing or popping strings.
Just make up your mind. You should be pushing and popping ints, or longs, or doubles, or BigDecimals, depending on what precision you need.
EDIT
buffer.push((double)c);
is invalid. You're pushing the ASCII value, not the numeric value it corresponds to. You need
buffer.push((double)Character.digit(c, 10));
You also need an else after each if block: if the character is a digit, it won't be a +, and if it's a + it won't be a -, etc.
I want to have a linked list containing an object
Here we have the class.
It is simple and only has a String and one int. Called s and n respectively.
public class test {
String string = new String ();
int n;
public metodo (String string, int n ){
sets(string);
setn(n);
}
public void sets(String string){
this.string = string;
}
public void setn(int n){
this.n = n;
}
public String gets(){
return string;
}
public int getn(){
return n;
}
}
In each node there will be an instance of the class test.
I want to be able to call each node and then call the object in the node calling the class test.
Here is my linked list
import java.io.*;
public class Node
{
BufferedReader br = new BufferedReader( new InputStreamReader ( System.in));
test m;
int n;
static Node next = null;
String string = new String ();
Nodo head = null;
public Nodo (test m, Nodo next) {
this.next = next;
}
public void hoho() throws IOException{
while ( true )
{ // This loop is for making several nodes with diferent information
System.out.println("String");
string n = br.readLine();
System.out.println(" Int ");
n = Integer.parseInt(br.readLine());
m = new test(string, n);
Nodo nod = new Nodo (m, null);
Nodo.siguiente = head;
head = nod;
if ( n == 0 ){ // Manual close of the loop by inserting 0
break;
}
}
}
}
Now I don't really know when to start the object m, if in the start or in the while.