Parsing a tree from a nested list in Java - java

I have to create a tree from a nested list of integers in Java, like this:
((3,8,(7,(3,0,7),(8,8,2))),
(4,(7,9,8),8),
(((3,6,4),2,6),((9,2,9),4,7,(6,4,5) ),4,(6,4,5))
)
would be parsed to this tree: https://gyazo.com/189e2a4936913f9025b501be86aabc35/
I just can't seem to visualize how the nested list becomes the tree...
NOTE, a blank space means the tree value is empty

It seems a node is either a leaf with a number, or a list of nodes:
public abstract class Node {
}
public class NumberNode extends Node {
private final int number;
public NumberNode(int number) {
this.number = number;
}
#Override
public String toString() {
return Integer.toString(number);
}
}
public class ListNode extends Node {
private final List<Node> list = new ArrayList<>();
public ListNode(Collection<Node> nodes) {
list.addAll(nodes);
}
#Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append('(');
boolean first = true;
for (Node node: list) {
if (first) {
first = false;
} else {
buf.append(',');
}
buf.append(node);
}
buf.append(')');
return buf.toString();
}
}
You may want to use a scanner to tokenize your input:
public class Scanner {
private final Reader in;
private int c;
private Token token;
private int number;
public static enum Token {LPAR,RPAR,NUMBER,COMMA,EOF};
public Scanner(Reader in) throws IOException {
this.in = in;
c = in.read();
}
public Token getToken() {
return token;
}
public int getNumber() {
return number;
}
public Token nextToken() throws IOException {
while (c == ' ') {
c = in.read();
}
if (c < 0) {
return token = Token.EOF;
}
if (c >= '0' && c <= '9') {
number = c - '0';
c = in.read();
while (c >= '0' && c <= '9') {
number = 10*number + (c-'0');
c = in.read();
}
return token = Token.NUMBER;
}
switch (c) {
case '(':
c = in.read();
return token = Token.LPAR;
case ')':
c = in.read();
return token = Token.RPAR;
case ',':
c = in.read();
return token = Token.COMMA;
default:
throw new RuntimeException("Unknown character " + c);
}
}
}
You can then write a parser:
public static Node parse(Reader in) throws IOException {
Scanner scanner = new Scanner(in);
scanner.nextToken();
return parse(scanner);
}
private static Node parse(Scanner scanner) throws IOException {
switch (scanner.getToken()) {
case NUMBER:
int value = scanner.getNumber();
scanner.nextToken();
return new NumberNode(value);
case LPAR:
scanner.nextToken();
List<Node> nodes = parseList(scanner);
if (scanner.getToken() != Token.RPAR) {
throw new RuntimeException(") expected");
}
scanner.nextToken();
return new ListNode(nodes);
default:
throw new RuntimeException("Number or ( expected");
}
}
private static List<Node> parseList(Scanner scanner) throws IOException {
List<Node> nodes = new ArrayList<>();
if (scanner.getToken() != Token.RPAR) {
nodes.add(parse(scanner));
while (scanner.getToken() == Token.COMMA) {
scanner.nextToken();
nodes.add(parse(scanner));
}
}
return nodes;
}
To parse your example:
String s = "((3,8,(7,(3,0,7),(8,8,2))), (4,(7,9,8),8), (((3,6,4),2,6),((9,2,9),4,7,(6,4,5) ),4,(6,4,5)) )";
System.out.println(s);
Node node = parse(new StringReader(s));
System.out.println(node);
Output:
((3,8,(7,(3,0,7),(8,8,2))), (4,(7,9,8),8), (((3,6,4),2,6),((9,2,9),4,7,(6,4,5) ),4,(6,4,5)) )
((3,8,(7,(3,0,7),(8,8,2))),(4,(7,9,8),8),(((3,6,4),2,6),((9,2,9),4,7,(6,4,5)),4,(6,4,5)))

Related

Chained Hashing Program; the method is undefined for the type error

I have made multiple methods, and they all have the error called
The method add(int, ChainHashEx.Data) is undefined for the type ChainHash<Integer,ChainHashEx.Data>
and there is another problem that is
The constructor ChainHash<Integer,ChainHashEx.Data>(int) is undefined
Why are the methods undefined? Is there something wrong with the class?
Or is there something wrong in someplace I am ignorant about.
adding code and the class with methods underneath.
code ChainHashEx :
package week14;
import java.util.Scanner;
public class ChainHashEx {
static Scanner sc = new Scanner(System.in);
static class Data {
private int no;
private String name;
public int keyCode() {
return no;
}
public String toString() {
return name;
}
void scanData(String guide, int sw) {
System.out.println(guide + "enter data to add");
if (sw == 1) {
System.out.print("number : ");
no = sc.nextInt();
System.out.print("name : ");
name = sc.next();
} else {
System.out.print("number : ");
no = sc.nextInt();
}
}
}
static void printMenu() {
System.out.println("1. add 2. delete 3. search 4. print 5. exit ");
}
public static void main(String[] args) {
int menu;
Data data;
Data temp = new Data();
ChainHash<Integer, Data> hash = new ChainHash<Integer, Data>(13);
do {
printMenu();
System.out.print("select menu: ");
switch(menu = sc.nextInt()) {
case 1 :
data = new Data();
data.scanData("add", 1);
hash.add(data.keyCode(), data);
break;
case 2 :
temp.scanData("delete", 2);
hash.remove(temp.keyCode());
break;
case 3 :
temp.scanData("search", 2);
Data t = hash.search(temp.keyCode());
if (t != null)
System.out.println("searched : " + t);
else
System.out.println("the data does not exist");
break;
case 4 :
hash.dump();
break;
}
} while (menu != 5);
System.out.println("stop program");
}
}
class ChainHash :
package week14;
public class ChainHash<K,V> {
class Node<K, V> {
private K key;
private V data;
private Node<K, V> next;
public Node(K key, V data, Node<K, V> next) {
this.key = key;
this.data = data;
this.next = next;
}
K getKey() {
return key;
}
V getValue() {
return data;
}
private int size;
private Node<K,V>[] table;
public void ChainHash(int capacity) {
try {
table = new Node[capacity];
this.size = capacity;
} catch (OutOfMemoryError e) {
this.size = 0;
}
}
public int hashValue(Object key) {
return key.hashCode() % size;
}
public V search(K key) {
int hash = hashValue(key);
Node<K,V> p = table[hash];
while (p != null) {
if (p.getKey().equals(key))
return p.getValue();
p = p.next;
}
return null;
}
public int add(K key, V data) {
int hash = hashValue(key);
Node<K,V> p = table[hash];
while (p != null) {
if (p.getKey().equals(key))
return 1;
p = p.next;
}
Node<K,V> temp = new Node<K,V>(key, data, table[hash]);
table[hash] = temp;
return 0;
}
public void dump() {
for (int i=0; i<size; i++) {
Node<K,V> p = table[i];
System.out.printf("%02d ", i);
while (p != null) {
System.out.printf("-> %s (%s) ", p.getKey(), p.getValue());
p = p.next;
}
System.out.println();
}
}
public int remove(K key) {
int hash = hashValue(key);
Node<K,V> p = table[hash];
Node<K,V> pp = null;
while (p != null) {
if (p.getKey().equals(key)) {
if (pp == null)
table[hash] = p.next;
else
pp.next = p.next;
return 0;
}
pp = p;
p = p.next;
}
return 1;
}
}
}
your ChainHash methods are defined inside the Node class, that's why they can't be found.
I think it's a "braces" error:
add a } after
V getValue() {
return data;
}
to "end" the Node class;
remove a } at the bottom of ChainHash;
remove void from the ChainHash constructor.
after these fixes the code should compile.

search(String target) method in a BinarySearchTree

I'm coding a dictionary system. This system should be run like this;
User enters a word that s/he wants to learn the definition.
The words and the definitions are storing in a linked list
while searching I should use a binary search tree
bst is comparing the words
search(String target) method should return the word+definition
Problems:
I've printed the linked list in a binary search tree but the method search() is couldn't return the word+definition? Where did I do a mistake?
public class BinarySearchTree {
private String data;
private BinarySearchTree left;
private BinarySearchTree right;
public BinarySearchTree() {
// I've deleted the getters/setters
public void addNode(String data) {
if (this.data == null) {
this.data = data;
} else {
if (this.data.compareTo(data)> 0) {
if (this.left != null) {
this.left.addNode(data);
} else {
this.left = new BinarySearchTree(data);
}
} else {
if (this.right != null) {
this.right.addNode(data);
} else {
this.right = new BinarySearchTree(data);
}
}
}
}
public boolean search(BinarySearchTree t,String key) {
if (t.data.equals(key)) return true;
if (t.left != null && search(t.left,key)) return true;
if (t.right != null && search(t.right,key)) return true;
return false;
}
}
public class Vocab {
public static void main(String args[])
{
LinkedList<String> ll
= new LinkedList<>();
Word word = new Word("Engineer", "Mühendis");
Word word2 = new Word("School", " Okul");
Word word3 = new Word("Pencil", "Kalem");
Word word4 = new Word("Window", "Pencere");
ll.add(word.toString());
ll.add(word2.toString());
ll.add(word3.toString());
ll.add(word4.toString());
for (int i = 0; i < ll.size(); i++) {
System.out.println(ll.get(i));
}
BinarySearchTree bst = new BinarySearchTree();
// Using the for each loop
for (String str : ll) {
bst.addNode(str);
}
System.out.println("search: " );
//here I want to return search() method and get the word+definition
}
}

Sending a queue through a constructor in java?

The goal is to pass a data structure(queue) through a constructor and return a new queue once it goes through a method. I created a method of type Queue that converts from infix to postfix order. The problem is, when I pass the queue through the constructor, I am outputting all 'a's instead of the equation itself. So, I know that the linked list is passing the LENGTH of the queue, but not the characters themselves.
Output:
a+b+c/(d+f)
aaaaaaaaaaa
Main Class:
import java.io.*;
import java.lang.*;
class Convert
{
static int Prec(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
public static QueueADT infixToPostFix(QueueADT in)
{
QueueADT infix = in;
QueueADT result = new QueueADT();
StackADT stack = new StackADT();
while(infix.empty() == false)
{
char c = infix.dequeue();
if (Character.isLetterOrDigit(c))
result.enqueue(c);
else if (c == '(')
stack.push(c);
else if (c == ')')
{
while (!stack.empty() && stack.peek() != '(')
result.enqueue(stack.pop());
stack.pop();
}
else // an operator is encountered
{
while (!stack.empty() && Prec(c) <= Prec(stack.peek()))
result.enqueue(stack.pop());
stack.push(c);
}
}
// pop all the operators from the stack
while (!stack.empty())
result.enqueue(stack.pop());
return result;
}
public static void main(String[] args)
{
QueueADT infix = new QueueADT();
String str = "a+b+c/(d+f)";
for(int i=0; i < str.length(); i++)
{
infix.enqueue(str.charAt(i));
System.out.print(str.charAt(i));
}
QueueADT postfix = infixToPostFix(infix);
System.out.println();
while(!postfix.empty())
{
System.out.print(postfix.dequeue());
}
}
}
Queue Class:
public class QueueADT
{
private int size;
private Node front;
private Node rear;
public QueueADT()
{
size = 0;
front = null;
rear = null;
}
public boolean empty()
{
return(size == 0);
}
public int size()
{
return size;
}
public void enqueue(char character)
{
Node newNode = new Node();
newNode.setData(character);
newNode.setNext(null);
if(this.empty())
{
front = newNode;
}
else
rear.setNext(newNode);
rear = newNode;
size++;
}
public char dequeue()
{
char i;
i = front.getData();
size--;
if(this.empty())
rear = null;
return i;
}
public char front()
{
return front.getData();
}
}
Stack class:
public class StackADT
{
private Node top;
private int size;
public StackADT()
{
top = null;
size = 0;
}
public boolean empty()
{
return (top == null);
}
public char peek()
{
return top.getData();
}
public int size()
{
return size;
}
public void push(char character)
{
Node newNode = new Node();
newNode.setData(character);
newNode.setNext(top);
top = newNode;
size++;
}
public char pop()
{
char i;
i = top.getData();
top = top.getNext();
size--;
return i;
}
public int onTop()
{
char i = pop();
push(i);
return i;
}
}
Node class:
public class Node
{
private char data;
private Node next;
public Node()
{
data = 0;
next = null;
}
public Node(char d)
{
data = d;
}
public Node(char d, Node n)
{
data = d;
next = n;
}
public void setData(char newData)
{
data = newData;
}
public void setNext(Node newNext)
{
next = newNext;
}
public char getData()
{
return data;
}
public Node getNext()
{
return next;
}
public void displayNode()
{
System.out.print(data);
}
}
Your implementation of dequeue method in QueueADT class is incorrect. You never change field "front", that's why when you call that method in your case, 'a' is always being returned. Add
front = front.getNext();
after line
char i = front.getData();
There are more problems with that code - try testing each of your methods separately, not only the program as a whole.

How to get all possible combinations of substrings?

I have a String of following structure:
A1(N1,N2,N3)P4(O3,O5)Y1.
How to get all combinations? The rule is that options inside parenthesis should not go together. For this example the output should be:
A1N1P4O3Y1,
A1N2P4O3Y1,
A1N3P4O3Y1,
A1N1P4O5Y1,
A1N2P4O5Y1,
A1N3P4O5Y1.
There can be parenthesis, but it can be without it. Another example:
N3P5(L1,L2)Q1, output should be:
N3P5L1Q1,
N3P5L2Q1.
Anyone with elegant solution?
The main idea is to transform a string input into a StringTemplate that holds parts, that can be a single string or a group of strings.
For each part, a iterator is created. While some iterator can go next, update a string array that holds current part values and reset all iterators of parts that come before the part that changed. Feel free to clear repeated code and add nested groups support and syntax verifications if needed.
private static StringTemplate parse(String string) {
List<StringPart> parts = new ArrayList<StringPart>();
boolean insideGroup = false;
StringBuilder currentToken = new StringBuilder();
List<LiteralPart> groupParts = new ArrayList<LiteralPart>();
for (int i = 0; i < string.length(); i++) {
char ch = string.charAt(i);
if (ch == '(') {
if (currentToken.length() != 0) {
parts.add(new LiteralPart(currentToken.toString()));
currentToken.delete(0, currentToken.length());
}
insideGroup = true;
} else if (ch == ')') {
if (insideGroup) {
if (currentToken.length() != 0) {
groupParts.add(new LiteralPart(currentToken.toString()));
currentToken.delete(0, currentToken.length());
}
parts.add(new CompositePart(groupParts));
groupParts.clear();
insideGroup = false;
} else {
currentToken.append(ch);
}
} else if (ch == ',') {
if (insideGroup) {
if (currentToken.length() != 0) {
groupParts.add(new LiteralPart(currentToken.toString()));
currentToken.delete(0, currentToken.length());
}
} else {
currentToken.append(ch);
}
} else {
currentToken.append(ch);
}
}
if (currentToken.length() != 0) {
parts.add(new LiteralPart(currentToken.toString()));
currentToken.delete(0, currentToken.length());
}
return new StringTemplate(parts);
}
private static final class StringTemplate {
private final List<StringPart> parts;
public StringTemplate(List<StringPart> parts) {
this.parts = parts;
}
public List<String> getCombinations() {
List<Iterator<String>> iterators = new ArrayList<Iterator<String>>(parts.size());
for (StringPart part : parts) {
iterators.add(part.getStrings().iterator());
}
String[] toJoin = new String[iterators.size()];
List<String> combinations = new ArrayList<String>();
int iteratorThatAdvanced;
int maxIteratorThatAdvanced = Integer.MIN_VALUE;
boolean first = true;
for (;;) {
iteratorThatAdvanced = -1;
for (int i = 0; i < iterators.size(); i++) {
Iterator<String> iterator = iterators.get(i);
if (first || iterator.hasNext()) {
String value = iterator.next();
toJoin[i] = value;
iteratorThatAdvanced = i;
if (!first && i >= maxIteratorThatAdvanced) {
maxIteratorThatAdvanced = i;
break;
}
}
}
if (iteratorThatAdvanced < 0) {
break;
}
if (!first) {
for (int i = 0; i < iteratorThatAdvanced; i++) {
Iterator<String> iterator = parts.get(i).getStrings().iterator();
iterators.set(i, iterator);
toJoin[i] = iterator.next();
}
}
combinations.add(join(toJoin));
first = false;
}
return combinations;
}
}
private static String join(String[] strings) {
StringBuilder builder = new StringBuilder();
for (String string : strings) {
builder.append(string);
}
return builder.toString();
}
private static abstract class StringPart {
abstract List<String> getStrings();
}
private static final class LiteralPart extends StringPart {
private final String literal;
public LiteralPart(String literal) {
this.literal = literal;
}
#Override
List<String> getStrings() {
return Collections.singletonList(literal);
}
}
private static final class CompositePart extends StringPart {
private final List<LiteralPart> parts;
public CompositePart(List<LiteralPart> parts) {
this.parts = new ArrayList<LiteralPart>(parts);
}
#Override
List<String> getStrings() {
List<String> strings = new ArrayList<String>(parts.size());
for (LiteralPart part : parts) {
strings.add(part.literal);
}
return strings;
}
}
Example:
public static void main(String[] args) {
StringTemplate template = parse("A1(N1,N2,N3)P4(O3,O5)Y1");
for (String combination : template.getCombinations()) {
System.out.println(combination);
}
template = parse("N3P5(L1,L2)Q1");
for (String combination : template.getCombinations()) {
System.out.println(combination);
}
}

Exception in thread "main" java.lang.NullPointerException virtual stack class

I am trying to use this class to evaluate postfix expressions and when testing it am thrown this exception at line 32 where the virtual stack should push.
public class PostfixEval
{
private IntStack s;
public PostfixEval()
{
IntStack s = new IntStack();
}
public boolean isInteger(String s)
{
int i = 0;
boolean isDigit = true;
while(i < s.length() && isDigit)
{
isDigit = s.charAt(i) >= '0' && s.charAt(i) <= '9';
i++;
}
return isDigit;
}
public int eval(String e)
{
String[] tokens = e.split("\\s+");
for(int i=0; i<tokens.length; i++)
{
if(isInteger(tokens[i]))
{
s.push(Integer.parseInt(tokens[i]));
}
else
{
int a,b,c;
b = s.pop();
a = s.pop();
c = 0;
char d = tokens[i].charAt(0);
if(d == '+')
{
c = a + b;
}
else if(d == '-')
{
c = a - b;
}
else if(d == '*')
{
c = a*b;
}
else if(d == '/')
{
c = a/b;
}
else if(d == '%')
{
c = a%b;
}
else
{
System.out.println("Error");
System.exit(0);
}
s.push(c);
}
}
return s.peek();
}
}
I have used jgrasp to see what Integer.parseInt(tokens[i])) evaluates to and confirm it is a number from the split string. When trying to push a number that I type into the paramater of the push method it works, so why do I get null exception when using the PostfixEval to push?
Here is my stack class.
public class IntStack implements StackIntADT
{
// fields
private int[] stk;
private int sp;
// constructors
public IntStack()
{
sp = -1;
stk = new int[10];
}
public IntStack( int s )
{
sp = -1;
stk = new int[s];
}
// stack class methods
public void push(int element)
{
if(!isFull())
{
sp++;
stk[sp]=element;
}
else
{
System.out.println("Element" + element);
System.exit(0);
}
}
public int pop()
{
int rv = 0;
if(!isEmpty())
{
rv = stk[sp--];
}
else
{
System.out.println(rv);
System.exit(0);
}
return rv;
}
public int peek()
{
return stk[sp];
}
public boolean isEmpty()
{
return sp==-1;
}
public boolean isFull()
{
return sp==stk.length-1;
}
public int size()
{
return stk.length;
}
public String toString()
{
String s = "";
for(int x=0;x<10;x++)
{
s = s + " " + stk[x];
}
return s;
}
}
The constructor should not define a local s variable (which hides the member variable with the same name). The member variable is never assigned a value.
Change the constructor to this:
public PostfixEval() {
s = new IntStack();
}

Categories

Resources