How to use a stack to parse a string - java

I have a String:
String stringContent="{\\*\\listtable{\\list{\\listlevel{\\leveltext}{\\levelNumber}}}}"
How do I select values of all enclosing braces one by one in each pass like this:
"{\\levelNumber}"
"{\\leveltext}"
"{\\listlevel{\\leveltext}{\\levelNumber}}"
"{\\list{\\listlevel{\\leveltext}}}"
"{\\*\\listtable{\\list{\\listlevel{\\leveltext}}}}"
So far I've done this:
public class StringExtracter {
public String stringofObject(Section parentSectionObject, String stringContent) {
Stack stack=new Stack();
String returnString = "";
char arr[] = stringContent.toCharArray();
for(int i=0;i<=arr.length;i++){
while(arr[i]!='}'){
if(arr[i]=='{'){
stringContent=stringContent.substring(i+1);
returnString=stringContent;
System.out.println(stringContent);
braces=true;
Section sectionObject=new Section(parentSectionObject,stringContent);
stack.push(arr[i]);
}
}
return returnString;
}
But the problem is that it is not detecting the right } like this. How should I be doing this?
Output as of now:
\*\listtable{\list{\listlevel{\leveltext}{\fefw}}}}
\list{\listlevel{\leveltext}{\fefw}}}}
\listlevel{\leveltext}{\fefw}}}}
\leveltext}{\fefw}}}}
\fefw}}}}

Stack-based solution (problably could be simpler, but let's solve the problem first):
public class Main {
public static class Node {
public int level;
public String content = "";
public List<Node> children = new ArrayList<>();
}
public static void main(String[] args) {
String input="{\\\\*\\\\listtable{\\\\list{\\\\listlevel{\\\\leveltext}{\\\\levelNumber}}}}";
Node root = null;
Stack<Node> stack = new Stack<>();
for(char c: input.toCharArray()) {
if (c == '{') {
Node n = new Node();
n.level = stack.size() + 1;
n.content += c;
stack.push(n);
if (root == null) root = n;
} else if (c == '}') {
Node n = stack.pop();
n.content += c;
if (!stack.isEmpty()) {
stack.peek().children.add(n);
}
} else {
stack.peek().content += c;
}
}
TreeTraverser<Node> treeTraverser = new TreeTraverser<Node>() {
#Override
public Iterable<Node> children(Node root) {
return root.children;
}
};
for(Node node : treeTraverser.preOrderTraversal(root)) {
String indent = String.format("%" + node.level + "s", " ");
System.out.println(indent + node.content);
}
}
}
Note: Google's Guava library is needed for the TreeTraverser
Output:
{\\*\\listtable}
{\\list}
{\\listlevel}
{\\leveltext}
{\\levelNumber}
Edit 1: modified to create a tree after additional input from the OP
Edit 2: modified to treat the siblings correctly

I recommend you to, instead of using a for loop, create a variable called i and increase it in the while loop. You're checking for "arr[i]!='}'" in the while loop, but as it's inside the for loop, i never increases, and therefore it's always checking the same character.

Related

I'm getting some logical error in Huffman's encoding java

Here is the code...
public class Huffman_Coding {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string to compress: ");
String str = sc.nextLine();
sc.close();
HashString hs = new HashString();
HashMap<Character, Integer> hm = hs.getStringHash(str);
PriorityQueue<Node> pq = new PriorityQueue<Node>();
for (char ch : hm.keySet()) {
pq.add(new Node(null, null, hm.get(ch), ch));
}
System.out.println(pq);
while (pq.size() != 1) {
Node left = pq.poll();
Node right = pq.poll();
Node parent = new Node(left, right, left.freq + right.freq, '\0');
pq.add(parent);
System.out.println(pq);
}
Huffman_Tree ht = new Huffman_Tree();
String ans = "";
ht.inOrder(pq.poll(), ans);
}
}
class Node implements Comparable<Node> {
#Override
public String toString() {
return "Node [freq=" + freq + ", ch=" + ch + "]";
}
Node lptr;
Node rptr;
int freq;
char ch;
Node(Node lptr, Node rptr, int freq, char ch) {
this.freq = freq;
this.lptr = lptr;
this.rptr = rptr;
this.ch = ch;
}
public int compareTo(Node o) {
int comparedvalue = Integer.compare(this.freq, o.freq);
if (comparedvalue != 0)
return comparedvalue;
else
return Integer.compare(this.ch, o.ch);
}
}
boolean isLeaf() {
return this.lptr == null && this.rptr == null;
}
}
class Huffman_Tree {
void inOrder(Node root, String code) {
if (!root.isLeaf()) {
inOrder(root.lptr, code + '0');
inOrder(root.rptr, code + '1');
} else
System.out.println(root.ch + " : " + code);
}
}
Here, for input string abccddeeee,
I'm getting something like:
[Node [freq=1, ch=a], Node [freq=1, ch=b], Node [freq=2, ch=c], Node [freq=2, ch=d], Node [freq=4, ch=e]]
[Node [freq=2, ch= ]]
I'm confused why in the second step Node having 'd' is coming ahead from 'e'. This is getting me errors in final encoding. Why compareTo method is failing I cant understand.
getHashString returns a Hash which has characters in key and their freq in value.
I can't figure out why the order of the elements in PriorityQueue is not the expected one after polling elements ant adding new "synthetic" elements, but I think you can solve the problem switching to a TreeSet, as I have done with success with
TreeSet<Node> pq = new TreeSet<Node>((n1, n2) -> n1.compareTo(n2)); // explicit but unnecessary comparator
and changind each pq.poll() invocation into pq.pollFirst()...
I hope this workaround can help you!
EDIT
As you can read in official PriorityQueue documentation, * The Iterator provided in method iterator() is not guaranteed to traverse the elements of the priority queue in any particular order. If you need ordered traversal, consider using Arrays.sort(pq.toArray()).*
This should explain why the toString() method invocation shows queue elements in an order different than the expected priority order...

Tree iterator in Java

I have implemented a code which adds elements in a tree and prints them in increasing order. However my aim is to learn iterators and want to replace the inOrder() function with an iterator function. How can I do this?
import java.util.InputMismatchException;
import java.util.Scanner;
import javax.xml.soap.Node;
class Tree
{
public final int mVal;
public Tree mLeft;
public Tree mRight;
public Node next;
public Tree(int val)
{
mVal = val;
}
public void add(int val)
{
if (val < mVal)
{
if (mLeft == null)
mLeft = new Tree(val);
else
mLeft.add(val);
}
else
{
if (val > mVal)
{
if (mRight == null)
mRight = new Tree(val);
else
mRight.add(val);
}
}
}
public String inOrder()
{
return ((mLeft == null) ? "" : mLeft.inOrder())
+ mVal + " "
+ ((mRight == null) ? "" : mRight.inOrder());
}
public static void main(String[] args)
{
Tree t = new Tree(8);
Scanner scanner = new Scanner(System.in);
boolean continueLoop = true; // determines if more input is needed
for (int i = 1; i < 9; ++i)
{
try // read two numbers and calculate quotient
{
System.out.print("Please enter a random integer : ");
int stackInt = scanner.nextInt();
t.add(Integer.valueOf(stackInt));
} // end try
catch (InputMismatchException inputMismatchException){
System.err.printf("\nException: %s\n", inputMismatchException);
scanner.nextLine(); //discard input so user can try again
System.out.println("You must enter integers. Please try again.\n");
} // end catch
}
System.out.println("Values in order = "+ t.inOrder());
}
}
look at this picture
First Step: if node has a left child, visit left child and do the first step with the child
Second Step: node has no left child (or we visited the left child already), add it to the inorder list
Third Step: first step with right child
i didnt test it
#Override
public String toString() {
return String.valueOf(mVal);
}
public String inOrder(Tree root) {
List<Tree> inOrder = new ArrayList<>();
inOrderRecursively(root, inOrder);
return inOrder.toString();
}
private void inOrderRecursively(Tree Node, List<Tree> inOrder) {
if (Node.mLeft != null) {
inOrderIt(Node.mLeft, inOrder);
}
inOrder.add(Node);
if (Node.mRight != null) {
inOrderIt(Node.mRight, inOrder);
}
}
greetings

Create a Binary Tree from postfix expression

Let's say I have the following postfix expression : 5372-*-
I want to create a binary tree from this expression. My algoritm is : If my char is number put it into a stack if it is an operator pop two elements from the stack and make them the childs of the operator. Then push the operator into the stack. Which seems like it is working but I cannot manage to connect the little trees that I create.
My current code is :
public void myInsert(char ch, Stack s) {
if (Character.isDigit(ch)) // initial cond.
s.push(ch);
else {
TreeNode tParent = new TreeNode(ch);
TreeNode t = new TreeNode(s.pop());
TreeNode t2 = new TreeNode(s.pop());
tParent.right = t;
tParent.left = t2;
s.push(ch);
System.out.println("par" + tParent.ch);
System.out.println("cright" + tParent.right.ch);
System.out.println("cleft" + tParent.left.ch);
}
}
My test class :
Stack stree = new Stack();
BST b = new BST();
String str = "5-3*(7-2)";
String postfix = b.convertToPosFix(str);
System.out.println(postfix);
for (char ch : postfix.toCharArray()) {
b.myInsert(ch, stree);
}
My output is :
par-
cright2
cleft7
par*
cright-
cleft3
par-
cright*
cleft5
Use a Stack of TreeNodes, not a Stack of chars. You have to combine the TreeNodes after all and not the chars:
public void myInsert(char ch, Stack<TreeNode> s) {
if (Character.isDigit(ch)) {
// leaf (literal)
s.push(new TreeNode(ch));
} else {
// operator node
TreeNode tParent = new TreeNode(ch);
// add operands
tParent.right = s.pop();
tParent.left = s.pop();
// push result to operand stack
s.push(tParent);
}
}
TreeNode
public class TreeNode {
public TreeNode right = null;
public TreeNode left = null;
public final char ch;
TreeNode(char ch) {
this.ch = ch;
}
#Override
public String toString() {
return (right == null && left == null) ? Character.toString(ch) : "(" + left.toString()+ ch + right.toString() + ")";
}
}
main
public static TreeNode postfixToTree(String s) {
Stack<TreeNode> stree = new Stack<>();
BST b = new BST();
for (char ch : s.toCharArray()) {
b.myInsert(ch, stree);
}
return stree.pop();
}
public static void main(String[] args) {
System.out.println(postfixToTree("5372-*-"));
System.out.println(postfixToTree("512+4*+3−"));
System.out.println(postfixToTree("51*24*+"));
}
This will print
(5-(3*(7-2)))
((5+((1+2)*4))−3)
((5*1)+(2*4))

How do I print my linked list?

If you look at my toString() method below, you can see that I have not finished it. I don't know how? Can anyone explain how I might proceed? Confused :-| I'm new to linked lists and so I automatically went for the Arrays.toString() approach before I realized that there is, of course, no arrays anywhere.
import java.util.Arrays;
public class LinkedIntegerStack {
private Node top = null;
private int size = 0;
public int size(){
return size;
}
public boolean isEmpty() {
if(top == null){
return true;
}
else{
return false;
}
}
public void push(int value) {
Node n = new Node(value);
n.next = top;
top = n;
size++;
}
public int top(){ //just returns a value..doesn't change structure
return top.element;
}
public int pop(){
if (isEmpty()){
throw new StackEmptyException();
}
int toReturn = top.element;
top = top.next;
size--;
return toReturn;
}
public String toString() {
return "[ Top = " + size +"]" + "[Stack = " );
}
private class Node {
int element;
Node next;
public Node(int value){
element = value;
}
}
public static void main(String[] args) throws StackEmptyException{
LinkedIntegerStack stack = new LinkedIntegerStack();
stack.push(17);
System.out.println(stack);
stack.push(11);
System.out.println(stack);
try{
stack.pop();
System.out.println(stack);
}
catch(StackEmptyException ex){
System.out.print("Stack is Empty: Error");
}
System.out.println("Stack: " + stack);
}
}
The solution is pretty easy.
It should be enough to iterate through the stack.
public String toString() {
String result = "[ Top = " + size +"]" + "[Stack = [";
if (top == null) {
return result + "]]";
Node temp = top;
while (temp != null) {
result += temp + ', '
temp = temp.next;
}
return result += temp.element + "]]";
}
Of course you should add at least getter methods to Node class, i.e. getElement() and getNext();
PS: the code isn't tested, but it should be fine.
System.out.println(Arrays.toString(stack.toArray()));
From https://stackoverflow.com/a/395403/2736496
JavaDoc: Arrays.toString(o[]), Collection.toArray(cll)

how to do this java recursive

I have this code:
static int countStu = 0;
public static int countStudent(Node<Student> lst) {
// pre : true
// post : res = number of students in list
if (lst != null) {
countStu++;
countStudent(lst.getNext());
}
return countStu;
}
The problem with this method is I must declare countStu outside the countStudent() method, which is not good in the case when I want to call countStudent() twice, it will make the returned value doubles. How do I solve this problem and able to call countStudent() unlimited times with correct results?
instead, return((lst == null)? 0 : (1 + countStudent(lst.getNext()))).
Change:
if(lst!=null){
countStu++;
countStudent(lst.getNext());
}
return countStu;
to
return lst==null ? 0 : (1+countStudent(lst.getNext()));
Assuming that this is your homework and you really must declare countStu outside (you shouldn't in any normal code), you can simply wrap the value in some class. Add set+get accessors and pass the object as a second argument to the function. Use it then, instead of the global / static variable.
Or simply don't use the variable at all and return the result + 1. Not sure if this is allowed by your rules.
In general when you are trying to do something like is useful to try to remove the explicit state handling somehow.
For example if you have to compute a function f(x) = G(f(x-1)) you can express G as a stateless method and follow the following pattern:
public static ResultType G(ResultType input) {
// compute G stateless
}
public static ResultType F(int x) {
return G(F(x - 1));
}
That way you don't have any side effects like you have with your current code. The downside is usually minor compared with what you are doing right now (the same stack depth is used overall).
The important thing is to make sure the G and F implementations are stateless (not using variables declared outside the method body scope).
Holding the state of the recursion in the static field would not be thread-safe. Instead hold the value in the stack.
I give you both a recursive example which would risk a StackOverflowError with as little as 6k nodes with a default heap as well as a loop version which doesn't suffer from this.
public class SO3765757 {
public static int countNodeRecursive(Node<?> node) {
if(node == null) {
debug("node is null");
return 0;
}
int count = 1 + countNodeRecursive(node.getNext());
debug(count + " = " + node.toString());
return count;
}
public static int countNodeLoop(Node<?> node) {
int count = 0;
for(Node<?> currentNode = node; currentNode != null; currentNode = currentNode.getNext()) {
count += 1;
debug(count + " = " + currentNode.toString());
}
return count;
}
public static void main(String[] args) {
int count = 10;
if(args.length > 0) {
try {
count = Integer.parseInt(args[0]);
} catch(NumberFormatException e) {
}
}
Node<Student> node = getNodeTest(count);
System.out.println("Loop count = " + countNodeLoop(node));
try {
System.out.println("Recursive count = " + countNodeRecursive(node));
} catch(StackOverflowError e) {
System.out.println("Recursive count caused " + e.getClass().getName());
}
}
private static void debug(String msg) {
System.out.println("DEBUG:" + msg);
}
private static <T> Node<T> getNodeTest(int count) {
Node<T> prevNode = null;
for(int i=0;i<count;i++) {
Node<T> node;
if(prevNode == null) {
node = new NodeImpl<T>();
} else {
node = new NodeImpl<T>(prevNode);
}
prevNode = node;
}
return prevNode;
}
private static interface Node<T> {
Node<T> getNext();
}
private static class NodeImpl<T> implements Node<T> {
private final Node<T> next;
public NodeImpl() {
this.next = null;
}
public NodeImpl(Node<T> next) {
this.next = next;
}
public Node<T> getNext() {
return next;
}
}
private static interface Student {
}
}
countStudent(lst.getNext());
why do i need to call again this , if lst.getNext() has null. precompute before calling recursion, there are different types.when u call this method countStudent from main method , check the lst value for not null , before recursion starts.
public static int
countStudent(Node lst) {
countStu++;
Node<Student> _tmp;
_tmp = lst.getNext();
if (_tmp != null )
countStudent(lst.getNext());
return countStu; }

Categories

Resources