How do I implement code to search word in a Trie? - java

Code: Search word in Trie
Implement the function SearchWord for the Trie class.
For a Trie, write the function for searching a word. Return true if the word is found successfully, otherwise return false.
Note: main function is given for your reference which we are using internally to test the code.
class TrieNode{
char data;
boolean isTerminating;
TrieNode children[];
int childCount;
public TrieNode(char data) {
this.data = data;
isTerminating = false;
children = new TrieNode[26];
childCount = 0;
}
}
public class Trie {
private TrieNode root;
public int count;
public Trie() {
root = new TrieNode('\0');
count = 0;
}
private boolean add(TrieNode root, String word){
if(word.length() == 0){
if (!root.isTerminating) {
root.isTerminating = true;
return true;
} else {
return false;
}
}
int childIndex = word.charAt(0) - 'a';
TrieNode child = root.children[childIndex];
if(child == null){
child = new TrieNode(word.charAt(0));
root.children[childIndex] = child;
root.childCount++;
}
return add(child, word.substring(1));
}
public void add(String word){
if (add(root, word)) {
this.count++;
}
}
public boolean search(String word){
// add your code here
return search(root,word);
}
private boolean search(TrieNode root, String word){
if(word.length()==0){
return true;
}
int childIndex = word.charAt(0) -'a';
TrieNode child = root.children[childIndex];
if(child==null){
return false;
}
return search(child, word.substring(1));
}
}
//Main Function
code
import java.io.*;
public class Runner {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException{
Trie t = new Trie();
String[] string = br.readLine().split("\\s");
int choice = Integer.parseInt(string[0]);
String word = "Null";
if (string.length!=1)
{
word = string[1];
}
while(choice != -1) {
switch(choice) {
case 1 : // insert
t.add(word);
break;
case 2 : // search
System.out.println(t.search(word));
break;
default :
return;
}
string = br.readLine().split("\\s");
choice = Integer.parseInt(string[0]);
if (string.length!=1)
{
word = string[1];
}
}
}
}

You need to make use of the isTerminating information. In search, change:
if(word.length()==0){
return true;
}
To:
if(word.length()==0){
return root.isTerminating;
}

Related

split strings with backtracking

I'm trying to write a code that split a spaceless string into meaningful words but when I give sentence like "arealways" it returns ['a', 'real', 'ways'] and what I want is ['are', 'always'] and my dictionary contains all this words. How can I can write a code that keep backtracking till find the best matching?
the code that returns 'a', 'real', 'ways':
splitter.java:
public class splitter {
HashMap<String, String> map = new HashMap<>();
Trie dict;
public splitter(Trie t) {
dict = t;
}
public String split(String test) {
if (dict.contains(test)) {
return (test);
} else if (map.containsKey(test)) {
return (map.get(test));
} else {
for (int i = 0; i < test.length(); i++) {
String pre = test.substring(0, i);
if (dict.contains(pre)) {
String end = test.substring(i);
String fixedEnd = split(end);
if(fixedEnd != null){
map.put(test, pre + " " + fixedEnd);
return pre + " " + fixedEnd;
}else {
}
}
}
}
map.put(test,null);
return null;
}
}
Trie.java:
public class Trie {
public static class TrieNode {
private HashMap<Character, TrieNode> charMap = new HashMap<>();
public char c;
public boolean endOWord;
public void insert(String s){
}
public boolean contains(String s){
return true;
}
}
public TrieNode root;
public Trie() {
root = new TrieNode();
}
public void insert(String s){
TrieNode p = root;
for(char c : s.toCharArray()) {
if(! p.charMap.containsKey(c)) {
TrieNode node = new TrieNode();
node.c = c;
p.charMap.put(c, node);
}
p = p.charMap.get(c);
}
p.endOWord = true;
}
public boolean contains(String s){
TrieNode p = root;
for(char c : s.toCharArray()) {
if(!p.charMap.containsKey(c)) {
return false;
}
p = p.charMap.get(c);
}
return p.endOWord;
}
public void insertDictionary(String filename) throws FileNotFoundException{
File file = new File(filename);
Scanner sc = new Scanner(file);
while(sc.hasNextLine())
insert(sc.nextLine());
}
public void insertDictionary(File file) throws FileNotFoundException{
Scanner sc = new Scanner(file);
while(sc.hasNextLine())
insert(sc.nextLine());
}
}
WordSplitter class:
public class WordSplitter {
public static void main(String[] args) throws FileNotFoundException {
String test = "arealways";
String myFile = "/Users/abc/Desktop/dictionary.txt";
Trie dict = new Trie();
dict.insertDictionary(myFile);
splitter sp = new splitter(dict);
test = sp.split(test);
if(test != null)
System.out.println(test);
else
System.out.println("No Splitting Found.");
}
}
Using the OP's split method and the implementation of Trie found in The Trie Data Structure in Java Baeldung's article, I was able to get the following results:
realways=real ways
arealways=a real ways
However, if I remove the word "real" or "a" from the dictionary, I get the following results:
realways=null
arealways=are always
Here's the entire code I used to get these results:
public class Splitter {
private static Map<String, String> map = new HashMap<>();
private Trie dict;
public Splitter(Trie t) {
dict = t;
}
/**
* #param args
*/
public static void main(String[] args) {
List<String> words = List.of("a", "always", "are", "area", "r", "way", "ways"); // The order of these words does not seem to impact the final result
String test = "arealways";
Trie t = new Trie();
for (String word : words) {
t.insert(word);
}
System.out.println(t);
Splitter splitter = new Splitter(t);
splitter.split(test);
map.entrySet().forEach(System.out::println);
}
public String split(String test) {
if (dict.find(test)) {
return (test);
} else if (map.containsKey(test)) {
return (map.get(test));
} else {
for (int i = 0; i < test.length(); i++) {
String pre = test.substring(0, i);
if (dict.find(pre)) {
String end = test.substring(i);
String fixedEnd = split(end);
if (fixedEnd != null) {
map.put(test, pre + " " + fixedEnd);
return pre + " " + fixedEnd;
} else {
}
}
}
}
map.put(test, null);
return null;
}
public static class Trie {
private TrieNode root = new TrieNode();
public boolean find(String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
TrieNode node = current.getChildren().get(ch);
if (node == null) {
return false;
}
current = node;
}
return current.isEndOfWord();
}
public void insert(String word) {
TrieNode current = root;
for (char l : word.toCharArray()) {
current = current.getChildren().computeIfAbsent(l, c -> new TrieNode());
}
current.setEndOfWord(true);
}
#Override
public String toString() {
return toString(root);
}
/**
* #param root2
* #return
*/
private String toString(TrieNode node) {
return node.toString();
}
public static class TrieNode {
private Map<Character, TrieNode> children = new HashMap<>() ;
private String contents;
private boolean endOfWord;
public Map<Character, TrieNode> getChildren() {
return children;
}
public void setEndOfWord(boolean endOfWord) {
this.endOfWord = endOfWord;
}
public boolean isEndOfWord() {
return endOfWord;
}
#Override
public String toString() {
StringBuilder sbuff = new StringBuilder();
if (isLeaf()) {
return sbuff.toString();
}
children.entrySet().forEach(entry -> {
sbuff.append(entry.getKey() + "\n");
});
sbuff.append(" ");
return children.toString();
}
private boolean isLeaf() {
return children.isEmpty();
}
}
public void delete(String word) {
delete(root, word, 0);
}
private boolean delete(TrieNode current, String word, int index) {
if (index == word.length()) {
if (!current.isEndOfWord()) {
return false;
}
current.setEndOfWord(false);
return current.getChildren().isEmpty();
}
char ch = word.charAt(index);
TrieNode node = current.getChildren().get(ch);
if (node == null) {
return false;
}
boolean shouldDeleteCurrentNode = delete(node, word, index + 1) && !node.isEndOfWord();
if (shouldDeleteCurrentNode) {
current.getChildren().remove(ch);
return current.getChildren().isEmpty();
}
return false;
}
}
}
I improved the original code by adding a toString() method to the Trie and TrieNode. Now, when I print out the Trie object "t", I get the following result:
{a={r={e={a=}}, l={w={a={y={s=}}}}}, w={a={y={s=}}}}
My conclusion is that the OP's TrieNode implementation is incorrect. The way the Trie is built, given the inputted string value, the behavior described by the OP seems to be correct.

Designing a Hamiltoninan path algorithm to find a cycle in a undirected graph

I have recently been working on developing a class to see the given undirected graph has a Hamiltonian cycle. I found out this interesting article http://www.geeksforgeeks.org/backtracking-set-7-hamiltonian-cycle/.I've developed my code accordingly. But the problem is the algorithms fails to return a hamiltoninan cycle.
Graph.java:
package graph;
public class Graph {
private static Map<String, Vertex> vertices = new HashMap<String, Vertex> ();
public static Map<String, LinkedList<Edges>> vertexs = new HashMap<String, LinkedList<Edges>>();
private static Vector<Vertex> verticesID =new Vector<Vertex>();
private static Vector<String> verticesIDString =new Vector<String>();
public Graph(String fileName) {
// TODO Auto-generated constructor stub
this.LoadGraph(fileName);
}
public int addVertex(String ID){
if (vertices.containsKey(ID))
return -1;
Vertex vertex=new Vertex(ID);
vertices.put(ID, vertex);
LinkedList<Edges> node =new LinkedList<Edges>();
vertexs.put(ID, node);
return 1;
}
public int addEdge(String from, String to, double weight){
//check whether the vertices exist or not
if (vertices.containsKey(from) && vertices.containsKey(to)){
vertices.get(from).addEdge(to, weight);
Edges newEdge = new Edges(from,to,weight);
if(vertexs.get(from) == null)
{
vertexs.put(from, new LinkedList<Edges>());
}
vertexs.get(from).add(newEdge);
return 1;
}
else{
System.err.println ("'From' vertex and/or 'to' vertex dosen't exist! ");
return -1;
}
}
private int LoadGraph(String fileName) {
File f;
BufferedReader in;
try {
f = new File(fileName);
in = new BufferedReader(new FileReader(f));
String delim = "[ ]+";
//String delim = "\t";
String from; String to;double weight;
int cnt = 0;
String line = in.readLine();
//System.out.println(line);
while (line != null) {
//String[] tokens=line.split(delim);
String[] tokens=line.split(delim,-1);
//if there're less than three entries (from,to, weight) then report err
if (tokens.length<3){
System.err.println ("Invalid line format. Line should be formated as: from to weight");
in.close();
return -1;
}
from=tokens[0];
to=tokens[1];
weight=Double.parseDouble(tokens[2]);
//first create the "from" vertex if it's not already created
this.addVertex(from);
//Then create the "to" vertex if it's not already created
this.addVertex(to);
//now associate the "from" vertex with "to" vertex using "weight"
this.addEdge(from, to,weight);
//do the association the other way around, i.e. force graph to be undirected.
this.addEdge(to, from,weight);
//if the "from" vertex is a new one, add it to the key vector
if (!verticesIDString.contains(from)) {
verticesIDString.add(from);
verticesID.add(new Vertex(from));
}
//if the "to" vertex is a new one, add it to the key vector
if (!verticesIDString.contains(to)) {
verticesIDString.add(to);
verticesID.add(new Vertex(to));
}
cnt++;
line = in.readLine();
//System.out.println(line);
}
in.close();
System.out.println(vertices.size());
System.out.println("Successfully added "+cnt+" associations");
return cnt;
} catch (IOException exc) {
System.err.println(exc.toString());
return -1;
}
}
public static ArrayList<Edges> getChildNodes(String node)
{
LinkedList<Edges> neighboursList;
Set<String> keys = vertexs.keySet();
for (String key : keys)
{
if (key.equals(node))
{
neighboursList = vertexs.get(key);
return new ArrayList<Edges>(neighboursList);
}
}
return new ArrayList<Edges>();
}
public Vertex getVertex(String ID){
return vertices.get(ID);
}
public static int getVerticesCount(){
return verticesID.size();
}
public static Vertex getVertexIdByIndex(int idx){
return verticesID.elementAt(idx);
}
public Vector<String> BFS(String start){
//Vector<String> tour = new Vector<String>();
Vector<String> visited = new Vector<String>();
LinkedList<String> queue = new LinkedList<String>();
visited.add(start);
queue.add(start);
while(queue.size() != 0){
String s = queue.poll();
//tour.add(s);
ArrayList<Edges> al = getChildNodes(s);
Iterator<Edges> i = al.listIterator();
while (i.hasNext())
{
String n = i.next().toVertex();
if (!visited.contains(n))
{
visited.add(n);
queue.add(n);
}
}
}
return visited;
}
}
Hamiltoninan.java:
package graph;
public class HamiltonianCycle {
public Vector<String> findHamiltonianCycle(Graph g,String start){
Vector<String> allVertex = g.BFS(start); //this will help us with all the vertices in the graph
Vector<String> path = new Vector<String>(); // To store the hamiltonian path
/*Initialize the path with null at first*/
for(int i=0;i < allVertex.size();i++){
path.add(null);
}
path.add(start); // add the start as the first vertex of the hamiltonian path
/**
*now the recursive functions
*cycle problem
**/
if (hamCycleUtil(g, path,allVertex) == false)
{
System.out.println("\nSolution does not exist");
return null;
}
return path;
}
//The utility function tha recursively finds the hamiltonian cycle
private boolean hamCycleUtil(Graph g, Vector<String> path,Vector<String> vers) {
// TODO Auto-generated method stub
if(path.size() == Graph.getVerticesCount()){
String s1 = path.lastElement();
ArrayList<Edges> LastNodeEdges = Graph.getChildNodes(s1);
for(Edges Node : LastNodeEdges){
if(Node.toVertex().equals(path.firstElement())){
System.out.println(path);
return true;
}
}
return false;
}
for(int i=1;i<vers.size();i++){
if(isSafe(vers.elementAt(i),g,path)){
path.add(vers.elementAt(i));
if(hamCycleUtil(g, path, vers) == true){
return true;
}
}
}
return false;
}
private boolean isSafe(String elementAt, Graph g, Vector<String> path) {
// TODO Auto-generated method stub
if(path.contains(elementAt)){
return false;
}
return true;
}
}
Can somebody point me out where the problem is and how can i solve the problem.
thanks,
Karthi.

How find suffix in tree

i am trying to make basic object oriented suffix tree console program and i dont know how to make boolean suffix(String s) method. My actual suffix method doesn't work properly. Finally it should looks like :
Node is for object, SuffixTree create tree and have methods for that tree, TestTree have main method for testing
Node
package trie3;
import java.util.HashMap;
import java.util.Map;
class Node{
private final char currentValue;
Map<Character,Node> children;
Node(){
this.currentValue = '#';
this.children = new HashMap<Character,Node>();
}
Node(char currentValue){
this.currentValue = currentValue;
this.children = new HashMap<Character,Node>();
}
char getValue(){
return this.currentValue;
}
void addChild(Node c){
this.children.put(c.getValue(),c);
}
boolean hasChild(Node c){
return this.children.containsKey(c.getValue());
}
Node getChild(Node c){
return this.children.get(c.getValue());
}
public String toString(){
char currentValue = this.getValue();
StringBuffer keys = new StringBuffer();
for(char key:this.children.keySet()){
keys.append("Current key:"+key+"\n");
}
return "Current value:"+currentValue+"\n"+
"Keys:"+keys.toString();
}
}
SuffixTree
package trie3;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import trie3.Node;
public class SuffixTree{
private Node root;
private void log(Object l){
System.out.println(l);
}
/*
* Helper method that initializes the suffix tree
*/
private Node createSuffixTree(String source,Node root){
for(int i=1;i<source.length();i++){
Node parent = new Node(source.charAt(i));
if(root.hasChild(parent)){
parent = root.getChild(parent);
}
Node current = parent;
for(int j=i+1;j<source.length();j++){
Node temp = new Node(source.charAt(j));
if(current.hasChild(temp)){
temp = current.getChild(temp);
}else{
current.addChild(temp);
}
current = temp;
}
root.addChild(parent);
}
return root;
}
/*
Creates the suffix tree from the given string
*/
public SuffixTree(String source){
this.root = createSuffixTree(source,new Node()); // jj to je vychozi s # jj jo
}
void printMap(Map<Character,Node> map){ // vytiskne vsechny znaky potomku daneho suffixu takze hahaa -- pokud budes od n tak to bude a h a a # tusim teda
for(char c:map.keySet()){
System.out.println("Current node has child: " +c);
}
}
boolean infix(String target){ // infix method
Map<Character,Node> rootChildren = this.root.children;
for(char c:target.toCharArray()){
if(rootChildren.containsKey(c)){
rootChildren = rootChildren.get(c).children;
}else{
return false;
}
}
return true;
}
boolean suffix(String target){ // like infix but last char must be leaf
Map<Character,Node> rootChildren = this.root.children;
for(int i=0;i<target.length()-1;i++){
printMap(rootChildren);
char c = target.charAt(i);
if(rootChildren.containsKey(c)){
rootChildren = rootChildren.get(c).children;
}else if(rootChildren == null){
System.out.println("hash");
return true;
}else{
return false;
}
}
return false;
}
testTree
public class testTree {
public static void main(String[] args){
SuffixTree sTree = new SuffixTree("hahaa");
//test suffix
if(sTree.infix("ha")){
System.out.println(":)");
}
else{
System.out.println(":(");
}
if(sTree.suffix("ha")){ // true only for a,ha,haa,ahaa
System.out.println(":)");
}
else{
System.out.println(":(");
}
//test substring
// sTree.printMap();
}
}

Java DFS implementation for n-puzzle, with hashmap

I'm writing program with several different algorithms for solving n-puzzle problem. I have problem with DFS algorithm, as it only finds solution for simplest combinations of depth 1 to 4, then it shows stack overflow error. Also, for depth 4 it shows solution of length 2147, which is obviously wrong. I ran out of ideas what is the problem.
I use HashMap to keep explored nodes and to retrace path. Here is my code for DFS:
public class DFS extends Path{
Node initial;
Node goal;
String order;
boolean isRandom = false;
ArrayList<Node> Visited = new ArrayList<Node>();
boolean goalFound=false;
public DFS(Node initial, String order, byte [][] goal_state){
this.initial=initial;
goal=new Node(goal_state);
this.order=order;
if(order.equals("Random"))isRandom=true;
Visited.add(initial);
path.put(this.initial, "");
runDFS(initial);
}
public void runDFS(Node current){
if(current.equals(goal))
{
goalFound=true;
System.out.println("Goal");
retracePath(current,true);
return;
}
if(!current.equals(goal) && goalFound==false)
{
Node child;
Moves m = new Moves(current);
if(isRandom)order=randomOrder("LRUD");
for (int i=0; i<4; i++)
{
String s = order.substring(i,i+1);
if(m.CanMove(s)==true)
{
child=m.move();
if(Visited.contains(child))
{
continue;
}
else
{
path.put(child,s);
Visited.add(child);
runDFS(child);
}
}
}
}
}
}
Node:
public class Node {
public byte[][] status;
private int pathcost;
public int getPathcost() {
return pathcost;
}
public void setPathcost(int pathcost) {
this.pathcost = pathcost;
}
public Node(byte[][] status)
{
this.status=new byte[status.length][status[0].length];
for(int i=0;i<status.length;i++){
for(int j=0;j<status[0].length;j++){
this.status[i][j]=status[i][j];
} }
}
#Override
public boolean equals(Object other)
{
if (!(other instanceof Node))
{
return false;
}
return Arrays.deepEquals(status, ((Node)other).status);
}
#Override
public int hashCode()
{
return Arrays.deepHashCode(status);
}
}
and Path:
public class Path {
public HashMap<Node,String> path;
public Path(){
path=new HashMap<Node, String>(100);
}
public void retracePath(Node nstate, boolean print){
String dir=path.get(nstate);
String textPath="";
int i=0;
while(!dir.equals("")){
textPath+=dir + ", ";
boolean changed=false;
if(dir.equals("L")) {dir="R"; changed=true;}
if(dir.equals("R") && changed==false) {dir="L";}
if(dir.equals("U")) {dir="D"; changed=true;}
if(dir.equals("D") && changed==false) {dir="U";}
Moves m=new Moves(nstate);
m.CanMove(dir);
nstate=new Node(m.move().status);
dir=path.get(nstate);
i++;
}
if(print==true) {textPath=textPath.substring(0,(textPath.length()-2));
System.out.println(i);
System.out.print(new StringBuffer(textPath).reverse().toString());}
}
public Node getParent(Node n){
String dir=path.get(n);
boolean changed=false;
if(dir.equals("L")) {dir="R"; changed=true;}
if(dir.equals("R") && changed==false) {dir="L";}
if(dir.equals("U")) {dir="D"; changed=true;}
if(dir.equals("D") && changed==false) {dir="U";}
Moves m=new Moves(n);
m.CanMove(dir);
n=new Node(m.move().status);
return n;
}
public String randomOrder(String order) {
ArrayList<Character> neworder = new ArrayList<Character>();
for(char c : order.toCharArray()) {
neworder.add(c);
}
Collections.shuffle(neworder);
StringBuilder newstring = new StringBuilder();
for(char c : neworder) {
newstring.append(c);
}
return newstring.toString();
}
}
If you have any ideas what is the problem and where is mistake I would be very thankful!

Java obj cloning problem

I would need some help with the following code if you are kind.
Basically i have a tree node that remembers it's parent node, depth-level and his current state(a 2D array).
Most variable names are written in my native language, i hope this is not a problem :
public class Nod implements Cloneable {
private Nod parinte;//parent node
private int[][] stare;//state
private int cost;//depth-level
private String actiune;//the action used to obtain this node
private volatile int hashCode = 0;
public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if (!(obj instanceof Nod))
{
return false;
}
Nod nod = (Nod)obj;
return cost == nod.getCost() && actiune.equals(nod.getActiune())
&& stare.equals(nod.getStareNod());
}
public int hashCode()
{
StringBuffer strBuff = new StringBuffer();
try
{
int n = Problema.Dimensiune();//returns the dimension of state matrix
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
strBuff.append(stare[i][j]);
strBuff.append(cost);
strBuff.append(actiune);
String str = strBuff.toString();
hashCode = str.hashCode();
}
catch (IOException e) {
e.printStackTrace();
}
return hashCode;
}
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
public static boolean goUp(int[][] st) throws IOException
{
int n = Problema.Dimensiune();
boolean ok = false;
int[][] a = st;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (a[i][j] == 0)
if (i != 0)
ok = true;
}
return ok;
}
public static boolean goDown(int[][] st) throws IOException
{
int n = Problema.Dimensiune();
boolean ok = false;
int[][] a = st;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (a[i][j] == 0)
if (i != (n-1))
ok = true;
}
return ok;
}
public static boolean goLeft(int[][] st) throws IOException
{
int n = Problema.Dimensiune();
boolean ok = false;
int[][] a = st;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (a[i][j] == 0)
if (j != 0)
ok = true;
}
return ok;
}
public static boolean goRight(int[][] st) throws IOException
{
int n = Problema.Dimensiune();
boolean ok = false;
int[][] a = st;
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
{
if (a[i][j] == 0)
if (j != (n-1))
ok = true;
}
return ok;
}
public static int[] Zero(int[][] st) throws IOException
{
int[][] a = st;
int n = Problema.Dimensiune();
int[] b = new int[2];
for (int i=0;i<n;i++)
for (int j=0;j<n;j++)
if (a[i][j] == 0)
{
b[0] = i;
b[1] = j;
}
return b;
}
public static int[][] Actiune(int[][] st, String s) throws IOException
{
int[][] a = st;
int[] b = Zero(st);
if ((goRight(st) == true) && (s == "right"))
{
a[b[0]][b[1]] = a[b[0]][b[1]+1];
a[b[0]][b[1]+1] = 0;
}
if ((goLeft(st) == true) && (s == "left"))
{
a[b[0]][b[1]] = a[b[0]][b[1]-1];
a[b[0]][b[1]-1] = 0;
}
if ((goUp(st) == true) && (s == "up"))
{
a[b[0]][b[1]] = a[b[0]-1][b[1]];
a[b[0]-1][b[1]] = 0;
}
if ((goDown(st) == true) && (s == "down"))
{
a[b[0]][b[1]] = a[b[0]+1][b[1]];
a[b[0]+1][b[1]] = 0;
}
return a;
}
public Nod(){}
public Nod (int[][] st)
{
parinte = null;
stare = st;
cost = 0;
actiune = null;
}
public Nod (Nod nod)
{
parinte = nod.parinte;
stare = nod.stare;
cost = nod.cost;
actiune = nod.actiune;
}
public Nod(Nod nodp, String ac) throws IOException
{
this.parinte = nodp;
this.cost = parinte.getCost()+1;
this.actiune = ac;
this.stare = Actiune(parinte.getStareNod(),actiune);
}
public void setCost(int cost)
{
this.cost = cost;
}
public int getCost(){
return this.cost;
}
public void setStareNod(int[][] stare)
{
this.stare = stare;
}
public int[][] getStareNod(){
return this.stare;
}
public void setNodParinte(Nod parinte)
{
this.parinte = parinte;
}
public Nod getNodParinte() throws IOException{
return this.parinte;
}
public void setActiune(String actiune)
{
this.actiune = actiune;
}
public String getActiune()
{
return this.actiune;
}
}
Now, i create an initial node and after, a child-node from it. The problem is that when i create the child-node, the parent's 2D array becomes identical with the child's array. I tried to clone the node object but it didn't fix it. I would appreciate if someone has an ideea how to fix it and shares it.
public class test {
public static void main(String[] args) throws IOException, CloneNotSupportedException
{
int[][] p = Problema.stareInitiala();
Nod nod = new Nod(p);
Nod nodc = (Nod) nod.clone();
Nod nod1 = new Nod(nodc,"right");
Nod nod1c = (Nod) nod1.clone();
Nod nod2 = new Nod(nod1c,"up");
if (nod.getStareNod().equals(nod.getStareNod()))
System.out.print("ok");
else
System.out.print("not ok");
}
}
So if p = {{7,2,4},{5,0,6},{8,3,1}} the if statement should return "not ok", but instead i get the "ok" message.
There is nothing broken or wrong about the clone mechanism. Just a bunch or programmers who don't understand it, here's a valid one for you class.
public Object clone() {
try {
Nod clone = (Nod)super.clone();
clone.stare = (int[][])stare.clone();
return clone;
} catch (CloneNotSupportedException cnse) {
//won't happen;
throw new RuntimeError("Won't happen");
}
}
This implementation assumes that the clone wants to use the same parent as the original. If this is not the case, you will need to clone that as well, or perhaps set the parent to null.
You may want to look at the documentation of the clone() method of Object. Default clone implementation (that is if you implemented Cloneable, which you did) performs shallow copy. This is probably not what you want, you may be better off by writing your own copying method.

Categories