Here's the gist of my code and it's function. It's a pick-where-you-go game to choose your path. For example, if you choose path a at the start, you get to choose between path d and e, and if you chose d you can move to f and g and so on.
I want to add backtracking. For instance, if I choose a in the beginning and go all the way to f, I want to be able to go back to d and have the choice between f and g again, or go all the way back to the starting point and choose b.
My initial thought was to use something to tell the code to go back to a certain line of code when I need to backtrack, but there's no goto in java to my understanding. I have an inkling to use loops. (I'm thinking while loops in particular.) I cannot figure out HOW to structure the loops to backtrack.
Here's my code:
public class PathGame {
public static void main (String[] args) {
String name = JOptionPane.showInputDialog("Hello! Welcome to my paths! What is your name, adventurer?");
JOptionPane.showMessageDialog(null, "Well then " + name + ", here's how this works...some generic instructions");
String startingChoice = JOptionPane.showInputDialog("Choose your path, a, b, or c.");
if (startingChoice.equals("a")){
String aChoice = JOptionPane.showInputDialog("Choose path d or path e");
if (aChoice.equals("d")) {
String dExamineChoice = JOptionPane.showInputDialog("path f or g?");
if (dExamineChoice.equals("f")) {
JOptionPane.showMessageDialog(null, name + "...!");
}
else if (dExamineChoice.equals("g")) {
JOptionPane.showMessageDialog(null, "Stuff g");
}
}
else if (aChoice.equals("e")) {
JOptionPane.showMessageDialog(null, "Stuff e");
}
else if (aChoice.equals("goBack")) {
///Backtrack back to start
}
}
else if (startingChoice.equals("b")) {
String bChoice = JOptionPane.showInputDialog("Path h or i?");
if (bChoice.equals("h")) {
String hChoice = JOptionPane.showInputDialog("Path j, k, or l?");
if (hChoice.equals("j")) {
String jExamine = JOptionPane.showInputDialog("m or n?");
if (jExamine.equals("m")) {
JOptionPane.showMessageDialog(null,"Stuff m");
}
else if (jExamine.equals("n")) {
JOptionPane.showMessageDialog(null,"Stuff n");
}
}
else if (hChoice.equals("k")) {
JOptionPane.showMessageDialog(null,"Stuff k");
}
else if (hChoice.equals("l")) {
JOptionPane.showMessageDialog(null,"Stuff l");
}
}
else if (bChoice.equals("i")) {
JOptionPane.showMessageDialog(null,"Stuff i");
}
}
}
}
Backtracking can be achieved with recursion. However, since you wanted the iterative approach. You can apply the same concept using a stack. Every time you visit a new square, push the current state into the stack. When you need to backtrack (for example you are in a dead end), pop out from the stack.
If your intention is to create something like a maze runner, you may want to record the visited squares.
And yes, you should be using a while-loop to do that.
Make an option back for each starting choice, such that when the user selects that option startingChoice is set to the letter you want to go back to.
There are two ways you could do this.
The extendable way would be to use a graph data structure. You could use something like JGraphT or TinkerPop. But that's assuming you want something really fancy. A graph would let you treat the whole path selection (traversal) very generically. It would let you design all sorts of paths and backtracking would simply be keeping track of where you came from.
The faster way would be to use a Stack data structure. Everytime you make a choice add that choice to your stack. So your current position is always stored at the top of the stack. When you backtrack just pop off the top of the stack and try again. For example:
public static void main(String []){
Stack<String> myPath = new Stack<>();
while(detinationNotReached){
myPath = goSomewhere(myPath);
}
}
public Stack goSomewhere(Stack<String> myPath){
String currentPosition = myPath.peek();
String choice = getChoice(currentPosition);
switch(choice){
case "a":
myPath.push("a");
break;
... //Other choices
case "back":
myPath.pop(); // This effectively backtracks.
break;
}
return myPath
}
Here's an example of how you store your possibilities in a graph data structure (i.e. a half-edge data structure):
class Edge {
public final Node end;
public Edge(Node end) { this.end = end; }
}
class Node {
public final int id;
public final List<Edge> edges;
public Node(int id, List<Edge> edges) { this.id = id; this.edges = Collections.unmodifiableList(edges); }
}
class Graph {
private final ArrayList<ArrayList<Edge>> halfEdges = new ArrayList<>();
private final ArrayList<Node> nodes = new ArrayList<>();
public Node addNode() {
ArrayList<Edge> edges = new ArrayList<>();
Node node = new Node(nodes.size(), edges);
halfEdges.add(edges);
nodes.add(node);
return node;
}
public Edge addEdge(Node from, Node to) {
assert nodes.contains(from) && nodes.contains(to);
Edge edge = new Edge(to);
halfEdges.get(from.id).add(edge);
return edge;
}
}
You'd use it like this:
class Game
{
public static void main (String[] args)
{
Graph graph = new Graph();
Node root = graph.addNode();
Node a = graph.addNode();
graph.addEdge(root, a);
Node b = graph.addNode();
graph.addEdge(root, b);
Node c = graph.addNode();
graph.addEdge(root, c);
Node d = graph.addNode();
graph.addEdge(a, d);
Node e = graph.addNode();
graph.addEdge(a, e);
// ...
// main loop
ArrayList<Node> path = new ArrayList<>();
StringBuilder builder = new StringBuilder();
while(true) {
if(path.isEmpty())
path.add(root);
Node pos = path.get(path.size() - 1);
builder.setLength(0);
builder.append("At ").append(pos.id).append(", choices: back");
for(Edge out : pos.edges)
builder.append(", ").append(out.end.id);
System.out.println(builder.toString());
// handle input: add chosen node to path or remove last entry if "back"
// ...
}
}
}
You can add any kind of data to a Node or an Edge, like an actual name for the choice to display (instead of id) etc...
Related
I'm trying to implement a bfs algorithm in Java,but it doesn't work as it should be.
I've made a game map comprised of HexTile objects(custom objects,similar to matrix elements). Each HexTile includes one adjacency list containing references to the elements that it's connected to, one function that returns those elements and one function that computes the distance between two HexTiles. The bfs algorithm is excecuted in another class called unit(units are placed in HexTiles) and finds every unit available in a given range from the room(currentTile). It then creates an ArrayList with the given units.
class HexTile {
static final int MAX_NEIGHBOURS = 6;
private HexTile[] neighbours;
public HexTile[] getNeighbours() {
return this.neighbours;
}
public double distanceFromTarget(HexTile target) {
double distance = Math.sqrt(Math.pow((this.getRow() - target.getRow()), 2) + Math.pow((this.getCol() - target.getCol()), 2));
return distance;
}
}
class Unit {
private ArrayList<Unit> unitsWithinRange = new ArrayList<Unit>();
private void findUnitsWithinRange(HexTile currentTile, int attackRange) {
Queue<HexTile> queue = new LinkedList<>();
ArrayList<HexTile> visited = new ArrayList<HexTile>();
queue.add(currentTile);
visited.add(currentTile);
while (!queue.isEmpty()) {
HexTile aux = queue.poll();
for (HexTile auxNeigh : aux.getNeighbours()) {
if (auxNeigh != null && (!visited.contains(auxNeigh))) {
visited.add(auxNeigh);
queue.add(auxNeigh);
}
}
if (aux != null && (currentTile.distanceFromTarget(aux) <= attackRange)) {
Unit auxUnit = aux.getUnitOnTile();
this.unitsWithinRange.add(auxUnit);
}
}
queue.clear();
visited.clear();
}
}
What happens whenever findUnitsWithinRange is excecuted is that it return a list of units,but the units that are in range 1 are not included(direct neighbours to root).Sometimes the program crashes,because units need to be able to know if there are any nearby units,to excecute some other functions.Any advice would be appreciated!
This is the Main class with main method for generating a double-ended list, remove and display its elements.
public class Main {
Link first, last;
public static void main(String args[]) {
Main ob = new Main();
Link arr[] = {
new Link(1), new Link(2), new Link(3)
};
int len = 3;
for(int i=0;i<len;i++)
ob.insertFirst(arr[i]);
System.out.print("Data in the list: ");
while(ob.first!=null)
System.out.print(ob.removeAndReturn()+", ");
for(int i=0;i<len;i++)
ob.insertLast(arr[i]);
System.out.print("\nData in the list: ");
while(ob.first!=null)
System.out.print(ob.removeAndReturn()+", ");
}
void insertFirst(Link arg) {
if(isEmpty())
last = arg;
arg.next = first;
first = arg;
}
// This removeAndReturn() method returns the Object data the link is holding and removes that Link from the list
Object removeAndReturn() {
Object ret = null;
try {
ret = first.data;
if(first.next==null)
last = null;
first = first.next;
}catch(NullPointerException NPe) {
System.out.println("You are referring to a null.\nLinked List is empty.");
}
return ret;
}
void insertLast(Link arg) {
if(isEmpty())
first = arg;
else
last.next = arg;
last = arg;
}
boolean isEmpty() {
return first==null;
}
}
class Link {
Object data;
Link next;
Link(Object data) {
this.data = data;
}
}
When executing, it gives the following output:
Data in the list: 3, 2, 1,
Data in the list: 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, ... {truncated}
Here the last two elements gets repeated in the output. I tried nullifying both the Link variables first and last before calling ob.insertLast(arr[i]) but it gives the same output.
Update:
private keywords are removed from the complete method signature for methods in the Main class other than main(String args[]) method and rmF() method is changed to removeAndReturn().
The main problem in your code lies in the fact that you're using the exact same nodes (the ones within the arr) to fill your list with head and tail insertions.
In fact, once you perform your first head insertion, those nodes have been linked to each other like this:
(3) => (2) => (1) => null
So, when you're performing your second insertion, you have that node 1 points to node 2, node 2 points to node 3, and theoretically node 3 should point to null since it's supposed to be the last element. However, node 3's next field is still pointing to node 2 from the previous insertion. This creates a loop where node 2 and node 3 keep pointing at each other; thus yielding the infinite loop you're experiencing.
(1) => (2) => <= (3)
To fix your problem you could either reset the next field of your nodes before re-using them (poor solution) or work with the actual data you need to structure rather than the nodes. In fact, the user of your class shouldn't be bothered with the details of your implementation and should only care about the info to be stored/represented (in your case int numbers).
This is a possible solution to your problem:
public class Main {
Link first, last;
public static void main(String args[]) {
Main ob = new Main();
//Array of int not of links
int[] arr = {1, 2, 3};
int len = 3;
for (int i = 0; i < len; i++)
ob.insertFirst(arr[i]);
System.out.print("Data in the list: ");
while (ob.first != null)
System.out.print(ob.removeAndReturn() + ", ");
for (int i = 0; i < len; i++)
ob.insertLast(arr[i]);
System.out.print("\nData in the list: ");
while (ob.first != null)
System.out.print(ob.removeAndReturn() + ", ");
}
//------ CORRECTION ------
//The method should receive the info the user needs to store.
//It will then be up to you to represent it as a Link or whatever
//internal structure you're going to use tomorrow. Don't bind the
//user to your internal implementation.
//------------------------
void insertFirst(int arg) {
//Generating a new node (or link) based on the given info
Link l = new Link(arg);
if (isEmpty())
last = l;
l.next = first;
first = l;
}
// This removeAndReturn() method returns the Object data the link is holding and removes that Link from the list
Object removeAndReturn() {
Object ret = null;
try {
ret = first.data;
if (first.next == null)
last = null;
first = first.next;
} catch (NullPointerException NPe) {
System.out.println("You are referring to a null.\nLinked List is empty.");
}
return ret;
}
//-------- CORRECTION --------
//same explanation given above
//----------------------------
void insertLast(int arg) {
//Generating a new node (or link) based on the given info
Link l = new Link(arg);
if (isEmpty())
first = l;
else
last.next = l;
last = l;
}
boolean isEmpty() {
return first == null;
}
}
Lastly, Do not capture RuntimeException. These are unchecked exceptions, not checked. You should investigate on their origin rather than simply catching them. What you've written is a bad practice.
https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
As #JayC667 has already said, you could improve some designing and naming of your class, methods and variables. There are some conventions, especially when talking about data structures. For example:
Your class is called Main but it describes a List, a name like MyList would have been better.
Your utility class, Link, could have been placed within MyList as a static nested class and probably named Node (it's a better fit).
Some of your methods' names were a bit too cryptic. Self-explanatory names will better help the users of your class.
Avoid accessing the internal state of another object from outside (list.first != null). Methods should be your way to go to interrogate an object's state.
Using generic types could have been a better implementation than just Object as generics provide: strict checks at compile time, avoid casting a more type safety, the ability to re-use the same code for different data types.
https://docs.oracle.com/javase/tutorial/java/generics/why.html
Here is a link to an implementation with the suggestions made above:
https://www.jdoodle.com/iembed/v0/s7C
I have begun to learn about binary search tree and I have done an exercise that asks me to make a family tree with a binary search tree.
I have already created it, but I have had some problems with it, so I am not sure if it is correct, and it has four variables: name, surname, father and mother, which make this tree totally different than all examples I have already seen. I will show what I have already done in the code bellow:
//I have created a class Ancestor
public class Ancestor {
String name;
String surname;
Ancestor father;
Ancestor mother;
public Ancestor (String name, String surname){
this.name = name;
this.surname = surname;
father = null;
mother = null;
}
public void printAncestor() {
System.out.println("Ancestors:"+"");
}
public void postOrder (Ancestor a) {
if (a == null) {
return;
}
else {
postOrder(a.mother);
postOrder(a.father);
a.printAncestor();
}
}
}
//Another class familyTree
public class familyTree {
static Ancestor root = null;
static void insertAncestor (String n, String s){
Ancestor temp = root;
Ancestor prev = null;
boolean notFound = true;
while (temp != null && notFound){
if (temp.name.equals(n) && temp.surname.equals(s)){
notFound = false;
break;
}
else if (n.compareTo(n)<0 && s.compareTo(s)<0){
prev = temp;
temp = temp.mother;
}
else {
prev = temp;
temp = temp.father;
}
}
if (notFound){
Ancestor a = new Ancestor(n, s);
if (prev == null) {
root = a;
}
else if (n.compareTo(n)<0 && s.compareTo(s)<0){
prev.mother = a;
}
else {
prev.father = a;
}
}
}
}
//And I have tried to create a family tree in the main class
public class Main {
public static void main(String[] args) {
// write your code here
familyTree f = new familyTree();
f.insertAncestor("Adam", "H");
f.insertAncestor("Charles", "B");
f.insertAncestor("Mary", "C");
f.insertAncestor("Matthew", "W");
f.insertAncestor("Jane", "X");
}
}
I would like to know if my classes make sense, because they show no error, but they still may be confusing. I would also like to know if I have created the family tree correctly, and based on my method to print the family tree, how would I print it? I have tried it like this:
f.postOrder();
But it did not work out. So I am not sure about what is the matter. As I said, the fact that the variables (name, surname, father, mother) are different from most of the examples on internet and other materials has made me confused. Anyway, I thank you all in advance.
So a couple of points. First of all a small style issue: You'd be better served using more descriptive variable names. You have a method signature that looks like:
static void insertAncestor (String n, String s)
Well, n and s don't make good parameter names. I can see from the context that n is for the name, and s is for the surname, but why not just call them name and surname?
In terms of actual code functionality, this line immediately jumped out at me:
else if (n.compareTo(n)<0 && s.compareTo(s)<0){
You're comparing n and s to themselves, so the comparison will always result in 0, and that if block will always be skipped, and will fall through to the else block.
What is the desired functionality there? How are you trying to determine whether or not to go down the mother's side or father's side of the tree? How would you indicate that "This new Ancestor should be inserted as the root's mother's mother's father's mother"? It may be the case that a binary tree just isn't the data structure that you should be using in the first place. Not every data structure is suitable for every problem.
I have a graph class with Node's, where each Node can connect to others:
public class Node {
List<Node> connections;
}
I would like to make a deep copy of the entire graph. As a first attempt, I tried making a copy constructor like:
public Node(Node other) {
connections = new ArrayList<Node>();
for (Node n : other.connections) {
connections.add(new Node(n));
}
}
So deep copying a graph would just be:
public Graph deepCopy () {
Graph g = new Graph();
g.nodes = new ArrayList<Node>();
for (Node n : nodes) {
g.nodes.add(new Node(n));
}
}
But that doesn't work as that destroys the connection relationship among the nodes. I am wondering if anyone has suggestions to do this in a simple way? Thanks.
The problem is that you need to copy the identities of the nodes, not just their values. Specifically, when you're copying some node, you need to deal with the identities of the nodes it refers to; that means that a copy constructor, or some other kind of purely local copying mechanism, can't do the job, because it only deals with one node at a time. I'm not sure that makes any sense, but I've typed it and my backspace key doesn't work.
Anyway, what you can do is pass around some other object which can tell which new node corresponds to which old node. If you wanted to be fancy (and who doesn't?) you could refer to this as a graph isomorphism. This can be something as simple as a map. As in this completely untested code:
// in Graph
public Graph deepCopy () {
Graph g = new Graph();
g.nodes = new ArrayList<Node>();
Map<Node, Node> isomorphism = new IdentityHashMap<Node, Node>();
for (Node n : nodes) {
g.nodes.add(n.deepCopy(isomorphism));
}
return g;
}
// in Node
public Node deepCopy(Map<Node, Node> isomorphism) {
Node copy = isomorphism.get(this);
if (copy == null) {
copy = new Node();
isomorphism.put(this, copy);
for (Node connection: connections) {
copy.connections.add(connection.deepCopy(isomorphism));
}
}
return copy;
}
Sergii mentions using serialization; serialization actually does something pretty similar when it traverses an object graph.
Yep, deep copy in java ( not only in java) can be made using memory serialization/deserialization
like this
public static Object copy(Object orig) {
Object obj = null;
try {
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return obj;
}
Kinda late input. But I had a similar problem but came to a different solution. But not shure if its bulletproof. So please feel free to comment so I can learn!
I have a Type called "Numbers" because I have no creativity naming stuff.
Each object of type "Numbers" has an internal list that can carry additional objects of type "Numbers" of which each has a list of additional "Numbers" of which each... and so on.
Basicaly you can make a tree structure similar to this:
I solved the deep copy problem by using a recursive copy-constructor inside the "Numbers" class.
Numbers class:
import java.util.ArrayList;
public class Numbers {
private ArrayList<Numbers> numbers = new ArrayList<>();
private int number;
public Numbers(int number) {
this.number = number;
}
public Numbers(Numbers numToCopy) {
this.number = numToCopy.getNumber();
ArrayList<Numbers> list = numToCopy.getNumbers();
for(int i = 0; i < list.size(); i++) {
Numbers n = new Numbers(list.get(i));
numbers.add(n);
}
}
public void addNumber(Numbers i) {
numbers.add(i);
}
public ArrayList<Numbers> getNumbers() {
return numbers;
}
public void setNumber(int i) {
this.number = i;
}
public int getNumber() {
return number;
}
public ArrayList<Numbers> getAllNumbers(ArrayList<Numbers> list) {
int size = numbers.size();
list.addAll(numbers);
for(int i = 0; i < size; i++) {
numbers.get(i).getAllNumbers(list);
}
return list;
}
}
Usage:
import java.util.ArrayList;
public class NumbersTest {
public NumbersTest() {
}
public static void main(String[] args) {
Numbers num0 = new Numbers(0);
Numbers num1 = new Numbers(1);
Numbers num2 = new Numbers(2);
Numbers num3 = new Numbers(3);
Numbers num4 = new Numbers(4);
Numbers num5 = new Numbers(5);
Numbers num6 = new Numbers(6);
num0.addNumber(num1);
num0.addNumber(num2);
num1.addNumber(num3);
num1.addNumber(num4);
num2.addNumber(num5);
num2.addNumber(num6);
num4.addNumber(num6);
//Deep copy here!
Numbers numCopy = new Numbers(num0);
//Change deep down in graph of original
num0.getNumbers().get(0).getNumbers().get(1).getNumbers().get(0).setNumber(799);
//Printout of copy to show it was NOT affected by change in original.
for(Numbers n : numCopy.getAllNumbers(new ArrayList<Numbers>())) {
System.out.println(n.getNumber());
}
}
}
Usage code shows that changing deep inside the "graph" of the original num0 object, does not change the copy made of it.
Theres two sixes (6) in the graph, and thats ok since they are on different branches.
Downside is if same number would repeat through one of the paths, like if there was a (1) somewhere under the first 1. It would then end up in an infinite loop.
Please do comment! :)
So in an interview, I was actually asked a simple question that goes like this, say that I have a nested JSON response, [a, b, c ,d [a, [b, [d, e], g], h]. I am asked to implement a class that basically can handle to store this data and a print method to do so, so here's what I have:
public class JSONode
{
private String str;
private JSONode nodes;
public JSONode (String a, ArrayList<String> n)
{
str = a;
nodes = n;
}
}
public class JSONResp
{
private ArrayList<JSONode> arr;
public JSONResp ()
{
arr = new ArrayList<JSONode>();
}
public boolean checkCircular(JSONode temp)
{
for (int i = 0; i < arr.size(); i++)
{
if (arr.get(i).nodes == temp)
return true;
}
return false;
}
public void add (JSONode nd)
{
if (!checkCircular(nd))
arr.add(nd);
}
public void recurseJSONode(JSONode)
{
if (!JSONode.node)
System.out.print(JSONode.str);
else {
System.out.print(JSONode.str);
recurseJSONode(JSONode.node);
}
}
public void print()
{
for (int i = 0; i < arr.size(); i++)
recurseJSONode(arr.get(i));
}
public static void main (String[] args) {
JSONResp x = new JSONResp();
x.add(new JSONode("a", null);
x.add(new JSONode("b", null);
}
}
Now he said that there will circular references issues when I print, in other words I have list A = [a, b, c, D] and D = [q, t, y, A]. So he said I'd have to prevent from adding D by using the checkCircular above. I made an attempt. Also just a node I know my recurseJSONode isn't correct and so does the print, so looking for a suggestion to fix that as well.. I am just curious to this problem.
The reason your circular check isn't right is that you only look for an existing duplicate of JSONode under the one node you're trying to add it to. But A might be under B and B is under A, so each is unique within its parent's list.
Re: using a stack for tracking activity in a recursive function:
Set<SomeNodeType> stack = new HashSet<SomeNodeType>();
someRecursiveThing(rootNode, stack);
And then inside someRecursiveThing:
void someRecursiveThing(SomeNodeType under, Set<SomeNodeType> stack) {
if (!stack.add(under)) {
return;
// continue happily, e.g. call self with child node,
// passing down the stack
SomeNodeType child = ...
someRecursiveThing(child, stack)
// finish by removing 'under' from the stack:
stack.remove(under);
}
The advantage of HashSet is that add and remove typically run in constant time - the size of the tree is irrelevant.
For comparison:
Markus Lausberg's answer suggests doing a complete recursive search of the whole tree, which would be O(N) where N is the number of nodes in the tree, and as you are doing that check for every node it ends up being O(N^2). A tree of 10 nodes will do 100 node comparisons; a tree of 1000 nodes will do 1000,0000 node comparisons.
In kan's answer the check involves searching the parent chain, which will depend on the depth of the tree. For a perfectly lopsided tree (worst case) the depth will be the same as the number of nodes, giving O(N^2) again. For a balanced tree the depth will be ~log N, not much better (remember, the check has to be done for every node).
The effect of these differences depends on the comparison operation used to determine if two nodes are the same. If it is just a pointer comparison (i.e. you only care if they're the same object) and the tree is never very large, the overhead of HashSet may have a negative impact. Whereas if you need to compare two nodes in a more complex way, so each comparison is expensive, and the tree is large, then the optimised lookup of HashSet will become beneficial.
First of all it should be like
public class JSONode
{
private String str;
private ArrayList<JSONode> nodes;
public JSONode (String a, ArrayList<JSONode> n)
{
str = a;
nodes = n;
}
}
You have to check recursivly, if the given node is part of the parent node and the parent of the parent and so on...
So more like
public static boolean checkCircular(JSONode temp)
{
if(temp == null){
return false;
}
ArrayList<JSONode> pNodes = temp.getChildrens();
for (int i = 0; i < nodes.size(); i++)
{
if (pNodes.get(i).getString().equals(temp.getString()))
return true;
if(checkCircular(temp))
return true;
}
return false;
}