I am working with java at the moment and I am trying to find out a way to stop printing to the console (for simplicity) after a certain index of a linkedList is reached. Any help explaining this would be much appreciated.
Below is my Node class used to create the list:
protected Integer data;
protected Node link;
public Node(Integer data, Node link) {
this.data = data;
this.link = link;
}
public Node addNodeAfter(Integer element) {
return link = new Node(element, link);
}
public String toString() {
String msg = "";
try {
if (link == null) {
msg = data + " null in tail";
} else {
msg = data + ", " + link.toString();
}
} catch (StackOverflowError e) {
// System.err.println("shit happened here");
}
return msg;
}
public Integer getData() {
return data;
}
public Node getLink() {
return link;
}
Create a method toString(int i) which takes as argument the number of elements which still have to be printed. If the argument is larger than zero and there is a valid link, then recursively call the toString(i - 1) method with i decreased by one:
Code:
public class Node {
public static void main(String[] args) {
Node linkedList = new Node(1, null);
Node node = linkedList;
for (int i = 2; i < 10; ++i)
node = node.addNodeAfter(i);
System.out.println(linkedList.toString(5));
}
public String toString(int i) {
if (i > 0) {
if (link == null)
return data.toString();
else
return data.toString() + " " + link.toString(i - 1);
} else
return "";
}
protected Integer data;
protected Node link;
public Node(Integer data, Node link) {
this.data = data;
this.link = link;
}
public Node addNodeAfter(Integer element) {
return link = new Node(element, link);
}
public Integer getData() {
return data;
}
public Node getLink() {
return link;
}
}
Output
1 2 3 4 5
You will need to extend the LinkedList class and override the toString() method, and then use your subclass.
Something like this:
public class MyLinkedList<E> extends LinkedList<E> {
#Override
public String toString() {
StringBuffer out = new StringBuffer("[");
for (int i=0; i < 3; i++) {
out.append(get(0).toString());
out.append(" ");
}
return out.toString();
}
}
And test it like this:
public class Main {
public static void main(String[] args) {
LinkedList<String> myList = new MyLinkedList<String>();
myList.add("one");
myList.add("two");
myList.add("three");
myList.add("four");
System.out.println(myList);
}
}
Related
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.
I've managed to make the doubly linked list into a circular one, I'm just having trouble making a method to remove the first element. I've tried looking at examples for single linked lists but I can't seem to modify it to fit my code. Any help would be greatly appreciated.
Linkedlist Class
package LinkedListS;
public class LinkedList {
private Node first;
private Node end;
LinkedList()
{
first = end = null;
}
public void addAtStart(int x){
Node temp = new Node(x);
if(first == null)
{
first = end = temp;
}
else
{
end.setNext(temp);
temp.setNext(first);
first = temp;
}
}
public void printFromStart()
{
Node temp = first;
do {
System.out.println(temp.getData());
temp = temp.getNext();
end.setNext(null);
} while (temp != null);
}
public void searchFromStart(int elementToBeSearched)
{
Node temp = first;
while(temp != null)
{
if (temp.getData() == elementToBeSearched)
{
System.out.println("Found " + elementToBeSearched);
return;
}
temp = temp.getNext();
}
System.out.println("Didn't find " + elementToBeSearched);
}
public void removeFirstElement(){
}
Driver Class:
enter code here
public class LinkedListMain {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
System.out.println("Going to add elements At Start");
ll.addAtStart(5);
ll.addAtStart(7);
ll.addAtStart(9);
ll.addAtStart(10);
System.out.println("Print the doubly linked list elements");
ll.printFromStart();
System.out.println("Search the following elements");
ll.searchFromStart(7);
ll.searchFromStart(1289);
ll.removeFirstElement();
ll.printFromStart();
}
}
Node Class:
package LinkedListS;
public class Node {
private int data;
private Node next;
private Node prev;
// Constructor to intialize/fill data
public Node(int data)
{
this.data = data;
}
// set the address of next node
public void setNext(Node temp)
{
this.next = temp;
}
// get the address of next node
public Node getNext()
{
return this.next;
}
public Node getPrev()
{
return this.prev;
}
public void setPrev(Node temp)
{
this.prev = temp;
}
// to get data of current node
public int getData()
{
return this.data;
}
}
For the removeFirstElement method I've tried these solutions with no avail:
Attempt #1
Node temp = first;
temp = null;
Attempt #2
Node temp = first;
if(first != null){
if(temp.getNext() == first){
first = null;
}
} else {
first = end;
end = first.getNext();
}
Attempt #3
Node temp = first;
if (first == null) {
System.out.println("There is no first element to remove");
} else
temp = first;
System.out.println(temp);
Attempt #4
Node temp = first;
end = null;
if(first != null){
if(temp.getNext() == temp){
first = null;
}
} else {
end = first;
first = first.getNext();
}
After scanning a few other methods that is what I found that works:
public void removeFirstElement(){
if (first != null){
first = first.getNext();
} else {
System.out.println("There is nothing to be removed");
}
}
I am new to Java and im working on implementing an unweighted directed Graph. Each Node holds an id and an object data. I am not sure about my approach so I need some advice on how to continue. Here's what im working with:
public class adjNode {
public String nodeId;
public Object data;
adjNode(String nodeId, Object data) {
this.data = data;
this.nodeId = nodeId;
}
}
public class Graph {
private Map<adjNode, List<adjNode>> map = new HashMap<>();
adjNode findNode(String nodeId) {
adjNode temp;
for (int i = 0; i < map.size(); i++) {
temp = (adjNode) map.get(i);
if (temp.nodeId == nodeId) {
return temp;
}
}
return null;
}
#Override
public void addNode(String name, Object data) {
adjNode newNode = new adjNode(name, data);
map.put(newNode, new LinkedList<>());
}
#Override
public Object getData(String nodeId) throws InvalidNodeException {
adjNode found = findNode(nodeId);
if (found != null) {
return found.data;
} else {
throw new InvalidNodeException(nodeId);
}
}
#Override
public void setData(String nodeId, Object data) throws InvalidNodeException {
adjNode found = findNode(nodeId);
if (found != null) {
found.data = data;
} else {
throw new InvalidNodeException(nodeId);
}
}
}
Does that make sense? Also how can I add directed edges and find incoming and outgoing neighbors?
Appreciate any help!
I was trying to do the deep copy of my linked list known as DictionaryNode which I did but i was not able to display it's content in display method as it is always null. why DictinaryNode temp is always null ? and if i try to assign temp = head work but with temp = copy doesn't.
public class ListOfNodes {
public class DictionaryNode {
protected String word;
private int level;
private DictionaryNode next;
private int space = 0;
public void displayCopy() {
DictionaryNode temp = copy.next;
while( temp != null ) {
System.out.println(temp.word)
temp = temp.next;
}
}
public DictionaryNode( String word, int level ) {
this.word = word;
this.level = level;
next = null;
}
}
private DictionaryNode head = null;
public DictionaryNode copy = null;
//used to do deep copy
public void Clone() {
DictionaryNode temp = head.next;
while( temp != null ) {
copy = new DictionaryNode( temp.word , temp.level );
copy = copy.next;
temp = temp.next;
}
}
public void displayCopy() {
DictionaryNode temp = copy.next;
while( temp != null ) {
Sytem.out.println(temp.word)
temp = temp.next;
}
}
This program will demonstrate how to do a deep copy on a list. It's more generic than your specific example so hopefully it helps others too.
public class Java_Practice {
private static class LinkedListTest {
private String data;
private LinkedListTest next;
public LinkedListTest(String data) {
super();
this.data = data;
}
public String getData() {
return data;
}
public LinkedListTest getNext() {
return next;
}
public void setNext(LinkedListTest next) {
this.next = next;
}
#Override
public String toString() {
return "LinkedListTest [data=" + data + ", next=" + next + "]";
}
}
// Do a deep copy
private static LinkedListTest copyLlt(LinkedListTest original) {
LinkedListTest copy = new LinkedListTest(original.getData() + " copied");
LinkedListTest nextCopy = original.getNext();
LinkedListTest current = copy;
while (nextCopy != null) {
LinkedListTest newCopy = new LinkedListTest(nextCopy.getData() + " copied");
newCopy.setNext(nextCopy.getNext());
current.setNext(newCopy);
current = newCopy;
nextCopy = newCopy.getNext();
}
return copy;
}
public static void main(String[] args) {
LinkedListTest firstLlt = new LinkedListTest("First");
LinkedListTest secondLlt = new LinkedListTest("Second");
LinkedListTest thirdLlt = new LinkedListTest("Thrid");
firstLlt.setNext(secondLlt);
secondLlt.setNext(thirdLlt);
LinkedListTest copiedLlt = copyLlt(firstLlt);
// Data should say First, Second, Third
System.out.println("Original LinkedListTest: " + firstLlt.toString());
// Data should say First Copied, Second Copied, Third Copied
System.out.println("Copied LinkedListTest: " + copiedLlt.toString());
}
}
In your Clone method you never assign a next field for the copied content. You need to do this to have more than a single connected node in the copy. Furthermore you need to copy the head too. Moreover do must not overwrite copy with anything but the copy of the head:
copy = new DictionaryNode(null, head.level);
DictionaryNode temp = head.next;
DictionaryNode current = copy;
while( temp != null) {
DictionaryNode nn = new DictionaryNode( temp.word , temp.level);
current.next = nn;
current = nn;
temp = temp.next;
}
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!