change values of array of a class in java - java

I am writting a program that performs an a star search throughout a map. I have created a class that hold all the nodes of the map.
public Node {
Node up_node, right_node, down_node, left_node;
}
public class Star {
public static void main(String args[]) {
Node a=new Node();
Node b=new Node();
Node h=new Node();
Node here=new Node();
Node[] NextNode;
NextNode = new Node[10];
for(int i=0;i<10;i++) {
NextNode[i]=new Node();
}
int j=0;
a.up_node=h;
a.right_node=b;
b.left_node=a;
h.down_node=a;
//if certain conditions are met
NextNode[j].here_node=a.up_node;
//what i was hoping to do is copy the node a.up which is h
}
}
into NextNode[0] in this case. However it keeps returning a memory address of some sort : test.Node#10b28f30: test being the name of the package, please help!

#override the toString() method to display the internal property of your class.
By default, java display the full class name#hashCode value.

Variables in Java are object references not actual objects. NextNode[j].here_node = a.up_node; will make NextNode[j].here_node and a.up_node point to the same object. Is this not what you want?
If you wanted to make a completely new copy of the object, then you can implement that in the Node class:
public class Node {
Node up_node, right_node, down_node, left_node;
public Node clone() {
Node ret = new Node();
// copy the properties
ret.up_node = this.up_node;
...
return ret;
}
}
Now
NextNode[j].here_node = a.up_node.clone();
will make a copy (although it's only a shallow one -- the copy will point to the same objects via its fields as opposed to copies of them).
I assume your confusion about the code returning "an address" comes because you tried to print a node, e.g.
System.out.println(a.up_node);
You'll get something like test.Node#10b28f30, but try
System.out.println(NextNode[j].here_node);
and you should get exactly the same string, indicating that they're pointing to the same object.
To get something nicer, you must override Node's implementation of toString(). Here's an example that will give each Node a unique number:
public class Node {
Node up_node, right_node, down_node, left_node;
// how many nodes were created
private static int count = 0;
// the number of this node
private int number;
public Node() {
// increment the number of nodes created
++Node.count;
// assign that number to this node
this.number = Node.count;
}
public String toString() {
return "Node #" + this.number;
}
}

We know that every class that we write are child of Object class. When we print a child of an Object it prints its toString() method. By default it is a hashed value of memory location. So it prints sort weird things. if we #overriding toString method to return something more meaningful to us then we can solve this problem. If we can name our node class someway I think we can keep track of them easily
class Node(){
String nameOfNode;
//contractor to keep track of where it goes.
public Node(String a){
nameOfNode=a;
}
//when we will print a Node it is going to print its name
public String toString(){
return nameOfNode;
}
}
Then it will print the name of the node. And it will stop showing that weird memory address.
and replace your new Node() with distinct name new Node("a name")

Related

Understanding setup for doubly linked list in Java

I am working on a doubly linked list in Java. So that I can create functions, I'm first working to understand the setup.
I have this code. I have started comments with what each line does. Looking at tutorials and I want to make sure I understand this correctly. I still get a little confused on using classes.
If I create a new node by Node x = new Node(); - I am creating a new node of class Node. So that creates an instance using "static class Node {"
Each Node created contains a int item, Node next, and Node prev, that I will set in my functions. The int item I assume is the contents of the Node.
What does the line "public Node() {}" do?
public class MyDeque {
Node first = null; //instance variable, first is of type node and is set to null
Node last = null; //instance variable, last is of type node and is set to null
int N = 0; //keeping track of number of nodes
static class Node {
public Node() { }
public int item;
public Node next; //next is of type node
public Node prev; //prev is of type node
}
To understand this setup for Double-Linked-List you need to understand how a constructor works; A constructor is like a method, which is used to initialize properties of a class when the object of this class is initialized in memory for the first time.
Let's take your code for an example, I modified it in a proper way to understand why and how constructors used in Java -
public class MyDeque {
Node first;
Node last;
int N;
public MyDeque(){
this.first = null;
this.last = null;
this.N = 0;
}
static class Node {
int item;
Node next;
Node prev;
public Node() {
this.next = null;
this.prev = null;
}
public void setItem(int item) {
this.item = item;
}
public int getItem(){
return this.item;
}
// ... public getters for other items
}
As you can see two constructors public Node(){} and public MyDeque(){} are used to set values for the properties of those objects when they are initialized in memory for the first time.
Later, of course, you can set / unchange / change values of properties using the setter method or using the "." operator but remember constructor will always take place when the objects are initialized or reinitialized in memory for the first time.

Constructor Node cannot be applied to given types while working with nodes

I am working on a code that puts new elements on MyStack if they are unique. I had to copy and paste the node starting code, so I'm having a bit of trouble with an issue. I keep getting two error messages, even after trying various workarounds and I'm not really understanding why. I've even tried using some helper functions I've previously made that have worked before so I'm extra confused.
The two errors I consistently get are:
-cannot infer type arguments for MyStack.Node (actual and formal arguments differ in length)
-constructor node cannot be applied to given types. Required, no arguments, found: anything,
Here's my code:
public class MyStack<Anything>
{
private Node first, last;
private class Node<Anything>
{
Anything item;
Node next;
}
public boolean contains(Anything value)
{
for (Node curr = first; curr != null; curr = curr.next)
{
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
public void add(Anything value)
//method that adds a new value to the end of the list
//COMPLETE
{
Node temp = first;
while(temp.next!=null){ //finds the end
temp=temp.next;
}
temp.next=new Node(value, null); //assigns new value
}
public void enqueue(Anything info){
if (this.contains(info)==true) { //if the info is already present
System.out.println("the stack already contains this value");
return;
}
//if we actually need to add the info
if (first == null) { //if there is nothing in the stack
Node temp= first;
first = new Node<>(info,temp);
first = temp;
return;
}
if (first != null) { //if there is already stuff
Node temp = first;
while (temp.next == null)
{ Node newNode= new Node<>(info, temp);
temp.next = newNode;
}
return;
}
}
}
As #Andreas already pointed out, Node needs a constructor.
There are a few other flaws in your Code:
Use Generics
With your Code, you can only store Objects of the class Anything, what strongly limits its reusability. Use a generic instead and you can reuse this class for many more purposes.
Linked List
I suggest, you use the paradigm of a double-linked-list. That way you do not need to find the last Node to add something to the Stack. Node now has a pointer to its previous and next element.
Use the last Object
You have the object last but never use it. To find out, whether the current object is the last one you compare the value to null. This has the effect, that storing a null value will break your List. Instead compare to the Object last, this object is unique and guarantees you, that you are at the end of the list. Both first and last are Nodes that do not contain a value and are simply used to mark the start/end of your List.
Adding elements
Using the changes above, the code in the Method enqueue(T value) becomes significantly simpler: You just check whether contains(value) and decide whether you add the value to the List or not.
All these changes applied result in following code:
public class MyStack<T extends Object> {
private Node first, last;
public MyStack() {
first = new Node(null, null, null);
last = new Node(null, null, first);
first.next = last;
}
private class Node {
T item;
Node next;
Node previous;
public Node(T item, Node next, Node previous) {
this.item = item;
this.next = next;
this.previous = previous;
}
}
public boolean contains(T value) {
for (Node curr = first.next; curr != last; curr = curr.next) {
if (value.equals(curr.item)) {
return true;
}
}
return false;
}
/**
* method that adds a new value to the end of the list
*/
public void add(T value)
{
Node secondLast = last.previous;
Node added = new Node(value, last, secondLast);
secondLast.next = added;
last.previous = added;
}
/**
* only adds value if it is not already contained by the Stack
*/
public void enqueue(T value) {
if (this.contains(value) == true) { // if the info is already present
System.out.println("the stack already contains this value");
}
else {
add(value);
}
}
public static void main(String[] args) {
MyStack<String> test = new MyStack<>();
test.add("foo");
test.add("bar");
test.add("baz");
System.out.println(test.contains("bar"));
System.out.println(test.contains("new"));
test.enqueue("baz");
test.enqueue("MyStack");
}
}
Naming
As you may have noticed, in my explanation I called this class a List. This is because it fulfills more of the characteristics of a List. A Stack usually only provides the methods push to put something at the top of the Stack and pop to remove and return the topmost Object. Optionally peek can return the topmost Object, without removing it from the Stack.
Also consider renaming the method enqueue: enqueue is used in Queues (obviously) and Queues do not forbid to add two equal Objects. So the name is misleading. I would call this method something like addIfNotContaining.
In my Opinion you should name this class to be a List and add a method get(int i) to get a specific element at a position. Naturally adding some other methods like size ect. to comply with a standard List. But I assume you already had, but did not post them because they are not related to your problem.
Multithreading
This Class is far from threadsave. But I let you figure out yourself how to make it threadsave if needed.

Getting Node Address instead of Value in Binary Search Tree

I've got a basic binary search tree in Java. I'm trying to output the variable value, but all I get are addresses instead of the value itself. Also, can someone explain the relation between the code in my inOrderTraversal method and how it relates to the display() in my Node class even though I'm not calling it myself? All I'm calling in main is addNode and inorderTraversal.
The following is my code:
class Node {
int value;
Node leftChild;
Node rightChild;
Node(int value, String name) {
this.value = value;
this.name = name;
}
public int displayNode() {
return value;
}
}
InOrderTraversal Method:
public void inOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
// Traverse the left node
inOrderTraverseTree(focusNode.leftChild);
// Visit the currently focused on node
System.out.print(focusNode + " ");
// Traverse the right node
inOrderTraverseTree(focusNode.rightChild);
}
}
Current Output: Node#7852e922 Node#4e25154f Node#70dea4e Node#5c647e05 Node#33909752 Node#55f96302
Desired Output: 5 10 15 20 25 30
I'm pretty familiar with C++, was just self-learning Java and ran into these peculiar issues.
I'm only getting addresses not values of the nodes
What is the link between inOrderTraversal and display()? I'm not even calling the display() method myself.
You're printing an object, not its inner value (in other words, you're calling toString() implicitly).
In order to print the value, you should get the value from Node object:
System.out.print(focusNode.displayNode() + " ");
Also I would recommend you to rename your displayNode() method to getValue(), as it is better explains what the method does.
And if you want your method to print something when calling System.out.println(object);, you should override toString() method in Node class:
#Override
public String toString() {
return this.value;
}
Then your code System.out.print(focusNode + " "); will display the node's value instead of object's address im memory.

Java Double Linked List

Alright, my professor (Data Structures class) assigned this: Your task is to write a program that can update character access frequencies in a doubly-Link list. The program should read one character at a time from a text file that contain many characters. To make it easier, do not count spaces. Every time a character is accessed, increment its access frequency by one in the node of the list. If the frequency of the current node is higher than of its previous node, the two nodes need to be swapped in the list. Continue doing so for all the previous nodes until no more previous node has lower access frequency. Eventually, the character with the highest frequency will appear at the beginning of the list, the next highest will be in the next node, etc. Your program also need to print out the characters in the list according to the order of the list.
Here is the program I have made so far. It's just a doubly linked list as of right now.
My main question is how should I go about the "Every time a character is accessed, increment its access frequency by one in the node of the list. If the frequency of the current node is higher than of its previous node, the two nodes need to be swapped in the list."?
I know there aren't any lines getting the info from a file. I'm going to add that later.
Any help is appreciated!
public class DoublyLinkedList {
private class Node {
String value;
Node next,prev;
public Node(String val, Node n, Node p) {
value = val;
next = n;
prev=p;
}
Node(String val) {
this(val, null, null);
}
}
private Node first;
private Node last;
public DoublyLinkedList() {
first = null;
last = null;
}
public boolean isEmpty(){
return first==null;
}
public int size(){
int count=0;
Node p=first;
while(p!=null){
count++;
p=p.next;
}
return count;
}
public void add(String e) {
if(isEmpty()){
last=new Node(e);
first=last;
}
else{
last.next=new Node(e, null, last);
last=last.next;
}
}
public void add(int index, String e){
if(index<0||index>size()){
String message=String.valueOf(index);
throw new IndexOutOfBoundsException(message);
}
if(index==0){
Node p=first;
first=new Node(e,p,null);
if(p!=null)
p.prev=first;
if(last==null)
last=first;
return;
}
Node pred=first;
for(int k=1; k<=index-1;k++){
pred=pred.next;
}
Node succ=pred.next;
Node middle=new Node(e,succ,pred);
pred.next=middle;
if(succ==null)
last=middle;
else
succ.prev=middle;
}
public String toString(){
StringBuilder strBuilder=new StringBuilder();
Node p=first;
while(p!=null){
strBuilder.append(p.value+"\n");
p=p.next;
}
return strBuilder.toString();
}
public String remove(int index){
if(index<0||index>=size()){
String message=String.valueOf(index);
throw new IndexOutOfBoundsException(message);
}
Node target=first;
for(int k=1; k<=index;k++){
target=target.next;
}
String element=target.value;
Node pred=target.prev;
Node succ=target.next;
if(pred==null)
first=succ;
else
pred.next=succ;
if(succ==null)
last=pred;
else
succ.prev=pred;
return element;
}
public boolean remove(String element){
if(isEmpty())
return false;
Node target=first;
while(target!=null&&!element.equals(target.value))
target=target.next;
if(target==null)
return false;
Node pred=target.prev;
Node succ=target.next;
if(pred==null)
first=succ;
else
pred.next=succ;
if(succ==null)
last=pred;
else
succ.prev=pred;
return true;
}
public static void main(String[] args){
DoublyLinkedList list1=new DoublyLinkedList();
String[] array={"a","c","e","f"};
for(int i=0; i<array.length; i++){
list1.add(array[i]);
}
list1.add(1,"b");
list1.add(3,"d");
System.out.println(list1);
}
}
Since this is a homework assigment, I'll only give hints:
Your Node class needs an extra field for a counter.
You need to iterate through the list to find the accessed character and increment its counter value.
You need a temporary Node object to swap nodes. Try it yourself first, then google it. It's an essential process every programmer must know.
I would recommend breaking down the procedure into the component parts. You know you need to keep and update a count, as Sebastian says above. You also know you need to be able to compare a node's count with the count of the node above it in the rankings. You know you need to be able to swap two nodes. You should have methods for those things. Think through what needs to happen in each broken-down method.
I always recommend a physical approach for these kinds of problems to get a feel for them: Try doing this with a set of note cards or post-it notes. On each one, write an object name and the fields for the Node object. Write field values in pencil. Jot down other fields (like the reference to the first element) on a sheet of paper. Then step through your algorithm and see what needs to change on each update. (note: Because this is a doubly-linked list, your changes should survive shuffling your stack of cards. Try that and see)
Good luck with the assignment!
Advice:
"I know there aren't any lines getting the info from a file.". You would be better off writing that code now, so that you can test what you have already written.
The other problem is that what you have written so far is a generic linked list, ignoring the requirement which say how the list is to be used. As a result, you have:
implemented a bunch of methods that appear to be unnecessary, and
not implemented the Node class correctly for the requirements.
Go back and look at the requirements, and work out what methods you actually need, and then implement them. (What you have done so far is a "bottom up" design that is largely ignoring what the top level needs. You would have been better of with a "top down" approach.)
The problem you are asked to solve is collating characters, not creating a "general purpose" linked list data structure.

java linked list copy constructor

Im having trouble with a constructor for a linked list. it takes a string and is supposed to create a node for every character.
i get a nullpointerexception everytime i try to print out the list. Does that mean that not even the first node is being created?
below is my node class and the list constructor.
class CharNode {
private char letter;
private CharNode next;
public CharNode(char ch, CharNode link)
{
ch = letter;
link = next;
}
public void setCharacter(char ch)
{
ch = letter;
}
public char getCharacter()
{
return letter;
}
public void setNext(CharNode next)
{
this.next = next;
}
public CharNode getNext()
{
return next;
}
}
and this is my constructor
// constructor from a String
public CharList(String s) {
CharNode newNode = head;
for(int i = 0; i <s.length(); i++)
{
newNode = new CharNode(s.charAt(i), null);
newNode.setNext(newNode);
}
}
am i constructing it correctly?
First of all, your attributions are switched around!
ch = letter;
link = next;
should be
letter = ch;
next = link;
Same thing in your setter.
When you have a method in Java of the form:
public void setSomething(String argument){
this.classMember = argument;
}
Is usually what you want. You must assign your argument to your class member, not the other way around.
Also, when you're invoking your constructor, you have:
newNode = new CharNode(s.charAt(i), null);
newNode.setNext(newNode);
This make it so that your "link" is always pointing to itself! Think about what you need to do to make the previous Node point to the node you've just created (perhaps save it somehow?)!
Was I clear enough? Let me know if I can explain further.
As pcalcao said, = assigns the value on the right to the variable on the left. You'll need to change ch = letter; to letter = ch; and link = next; to next = link;
Now, the line CharNode newNode = head; doesn't mean anything unless you've specified what head is prior to the code you've given, but it doesn't look like it. Remember that when creating a linked list, you don't start with anything, so even "special" nodes like head must be created (instantiated, if you prefer). The idea is to create the first node (the head), and then assign head to that first node. For every node after the first one, this step isn't required, as you simply are adding to the end of the list.
Finally, during construction, you'll need a reference to both a new node (like you have now), and the previous node, in order to do proper appending. Your code now is simply setting the next node in the list to the current node, which means that once you create a new newNode, you will lose the reference to the previous newNode.
A good way to approach linked lists when one is first getting started is to draw out what you want to do step by step, then try and translate that into code. Hopefully this is helpful.

Categories

Resources