We have an input string in this format "(1(2(4)(5))(3(6(8)(9))(7)))"
We have to build a Binary Tree such that 1 is the root node and the first complete bracket contains (2(4)(5)) contains the family of 1's left child
and (3(6(8)(9))(7)) is the family of the right child of the root A.
Finally the tree will look like this.
Like this
I am not able to find the exact algorithm to write convert this one. Thanks in Advance!
Think Stack.
When you see a "(" push the element onto the stack, when you see a ")" pop the stack, but assign it as a child to the top element of the stack.
So lets go through the example "( 1 ( 2 ( 4 ) ( 5 ) ) ( 3 ( 6 ( 8 ) ( 9 ) ) ( 7 ) ) )"
(1 -> push 1
(2 -> push 2
(4 -> push 4
) -> pop 4, but assign 4 as child to top of stack which is 2 ( see if left is available then assign as left child otherwise right child )
Current tree :
(5 -> push 5
) -> pop 5, top of the stack is still 2 ( left is not available so assign it as right child of 2 )
Current tree:
) -> pop 2, top of the stack is 1 ( left of 1 is available, so assign 2 as left child of 1)
Current tree:
(3 -> push 3
(6 -> push 6
(8 -> push 8
) -> pop 8, top of the stack 6's left is available assign 8 as left of 6
Current tree:
(9 -> push 9
) -> pop 9 -> add it to top of stack's right child i.e. 6's right child because 6's left is taken as 8.
Current tree:
) -> pop 6 -> add it to top of stack i.e. 3's left child as it is available.
Current tree:
(7 -> push 7
) -> pop 7 -> add it to top of stack i.e. 3's right child because 3's left child is taken as 6.
) -> pop 3 -> add it to top of stack i.e. 1's right child because 1's left child is taken as 2.
Current tree:
) -> pop 1 -> there is nothing in the stack now. Done.
Complete runnable example in Java with implementation using a stack is:
import java.util.*;
public class Main
{
public static void main(String[] args) {
TreeNode root = buildTree("(1(2(4)(5))(3(6(8)(9))(7)))");
levelOrder(root);
}
static class TreeNode {
int val;
TreeNode left, right;
public TreeNode(int val) {
this.val = val;
}
}
private static TreeNode buildTree(String s) {
Deque<TreeNode> dq = new ArrayDeque<>();
TreeNode rootNode = null;
for ( int i = 0; i < s.length(); i++ ) {
if ( s.charAt(i) == '(' ) {
Integer current = Integer.parseInt(String.valueOf(s.charAt(i+1)));
dq.push(new TreeNode(current));
} else if ( s.charAt(i) == ')' ) {
TreeNode node = dq.pop();
if ( dq.isEmpty() ) {
break;
} else {
rootNode = dq.peek();
if (rootNode.left == null) {
rootNode.left = node;
} else {
rootNode.right = node;
}
}
}
}
return rootNode;
}
private static void levelOrder(TreeNode root) {
Deque<TreeNode> dq = new ArrayDeque<>();
dq.offer(root);
while(!dq.isEmpty()) {
int sz = dq.size();
for ( int i = 0; i < sz; i++ ) {
TreeNode node = dq.poll();
System.out.print(node.val + " ");
if ( node.left != null ) {
dq.offer(node.left);
}
if ( node.right != null ) {
dq.offer(node.right);
}
}
System.out.println();
}
}
}
Of course, I can't just write the code for your assignment here :-) but I think it may help if you think on each symbol as an operation, for example
( = down
1 = add
( = down
2 = add
( = down
4 = add
) = up (goes to level of 2)
( = down
5 = add
) = up (goes to level of 2)
) = up (goes to level of 1)
( = down
3 = add
( = down
6 = add
( = down
8 = add
) = up (goes to level of 6)
( = down
9 = add
) = up (goes to level of 6)
) = up (goes to level of 3)
( = down
7 = add
) = up (goes to level of 3)
) = up (goes to level of 1)
) = up (leaves)
If you think in terms of a recursive algorithm, you may think of "going down" as a recursive method call and "going up" as returning from the recursive method call (which happens automatically, then the method itself completes).
I strongly suggest you to try to solve the problem because it's really important to learn.
However, if you still can't find the solution, you may find some detailed explanation here on how to solve it. https://www.geeksforgeeks.org/construct-binary-tree-string-bracket-representation/
The string lists the nodes in preorder sequence. So a recursive solution would be a possible choice.
In JavaScript you'd write it as follows:
class Node {
constructor(value) {
this.value = value;
this.children = [];
}
}
function createTree(str) {
// Extract numbers and parentheses from input into an array
let tokens = str.match(/\d+|./g);
if (!tokens) return null;
let i = 1; // skip first character, as it must be a "("
function recur() {
let node = new Node(tokens[i++]);
while (tokens[i++] != ")") {
node.children.push(recur());
}
return node;
}
return recur();
}
// Demo run
let str = "(1(2(4)(5))(3(6(8)(9))(7)))";
let tree = createTree(str);
// Output the tree in JSON format
console.log(JSON.stringify(tree, null, 2));
Note that this implementation does not perform any validation of the input. It is assumed that the input has a correct syntax.
The algorithm will accept encodings of non-binary trees, as this format may encode nodes that have any number of children.
Related
i have this code , Breadth First search
This code to represent graph , the search algorithm Breadth search , I want you to question on it and it is
void BFS(int s)
{
// Mark all the vertices as not visited(By default
// set as false)
boolean visited[] = new boolean[V];
// Create a queue for BFS
LinkedList<Integer> queue = new LinkedList<Integer>();
// Mark the current node as visited and enqueue it
visited[s]=true;
queue.add(s);
while (queue.size() != 0)
{
// Dequeue a vertex from queue and print it
s = queue.poll();
System.out.print(s+" ");
// Get all adjacent vertices of the dequeued vertex s
// If a adjacent has not been visited, then mark it
// visited and enqueue it
Iterator<Integer> i = adjacent_List[s].listIterator();
while (i.hasNext())
{
int n = i.next();
if (!visited[n])
{
visited[n] = true;
queue.add(n);
}
}
}
}
I want to follow the path if you start from point 0 to look for point three, how can I modify the code to print the points it passed!
So you store tracks in Stack and print them
Define a parent array where when you visit each node n in your loop, you set par[n]=s
in the end you should create a for-loop to get a chain of parents from three to 0
for (int i=3 ; i!=0 ; i=par[i])
cout << i << " ";
We need to find the maximum element in an array which is also equal to product of two elements in the same array. For example [2,3,6,8] , here 6=2*3 so answer is 6.
My approach was to sort the array and followed by a two pointer method which checked whether the product exist for each element. This is o(nlog(n)) + O(n^2) = O(n^2) approach. Is there a faster way to this ?
There is a slight better solution with O(n * sqrt(n)) if you are allowed to use O(M) memory M = max number in A[i]
Use an array of size M to mark every number while you traverse them from smaller to bigger number.
For each number try all its factors and see if those were already present in the array map.
Here is a pseudo code for that:
#define M 1000000
int array_map[M+2];
int ans = -1;
sort(A,A+n);
for(i=0;i<n;i++) {
for(j=1;j<=sqrt(A[i]);j++) {
int num1 = j;
if(A[i]%num1==0) {
int num2 = A[i]/num1;
if(array_map[num1] && array_map[num2]) {
if(num1==num2) {
if(array_map[num1]>=2) ans = A[i];
} else {
ans = A[i];
}
}
}
}
array_map[A[i]]++;
}
There is an ever better approach if you know how to find all possible factors in log(M) this just becomes O(n*logM). You have to use sieve and backtracking for that
#JerryGoyal 's solution is correct. However, I think it can be optimized even further if instead of using B pointer, we use binary search to find the other factor of product if arr[c] is divisible by arr[a]. Here's the modification for his code:
for(c=n-1;(c>1)&& (max==-1);c--){ // loop through C
for(a=0;(a<c-1)&&(max==-1);a++){ // loop through A
if(arr[c]%arr[a]==0) // If arr[c] is divisible by arr[a]
{
if(binary_search(a+1, c-1, (arr[c]/arr[a]))) //#include<algorithm>
{
max = arr[c]; // if the other factor x of arr[c] is also in the array such that arr[c] = arr[a] * x
break;
}
}
}
}
I would have commented this on his solution, unfortunately I lack the reputation to do so.
Try this.
Written in c++
#include <vector>
#include <algorithm>
using namespace std;
int MaxElement(vector< int > Input)
{
sort(Input.begin(), Input.end());
int LargestElementOfInput = 0;
int i = 0;
while (i < Input.size() - 1)
{
if (LargestElementOfInput == Input[Input.size() - (i + 1)])
{
i++;
continue;
}
else
{
if (Input[i] != 0)
{
LargestElementOfInput = Input[Input.size() - (i + 1)];
int AllowedValue = LargestElementOfInput / Input[i];
int j = 0;
while (j < Input.size())
{
if (Input[j] > AllowedValue)
break;
else if (j == i)
{
j++;
continue;
}
else
{
int Product = Input[i] * Input[j++];
if (Product == LargestElementOfInput)
return Product;
}
}
}
i++;
}
}
return -1;
}
Once you have sorted the array, then you can use it to your advantage as below.
One improvement I can see - since you want to find the max element that meets the criteria,
Start from the right most element of the array. (8)
Divide that with the first element of the array. (8/2 = 4).
Now continue with the double pointer approach, till the element at second pointer is less than the value from the step 2 above or the match is found. (i.e., till second pointer value is < 4 or match is found).
If the match is found, then you got the max element.
Else, continue the loop with next highest element from the array. (6).
Efficient solution:
2 3 8 6
Sort the array
keep 3 pointers C, B and A.
Keeping C at the last and A at 0 index and B at 1st index.
traverse the array using pointers A and B till C and check if A*B=C exists or not.
If it exists then C is your answer.
Else, Move C a position back and traverse again keeping A at 0 and B at 1st index.
Keep repeating this till you get the sum or C reaches at 1st index.
Here's the complete solution:
int arr[] = new int[]{2, 3, 8, 6};
Arrays.sort(arr);
int n=arr.length;
int a,b,c,prod,max=-1;
for(c=n-1;(c>1)&& (max==-1);c--){ // loop through C
for(a=0;(a<c-1)&&(max==-1);a++){ // loop through A
for(b=a+1;b<c;b++){ // loop through B
prod=arr[a]*arr[b];
if(prod==arr[c]){
System.out.println("A: "+arr[a]+" B: "+arr[b]);
max=arr[c];
break;
}
if(prod>arr[c]){ // no need to go further
break;
}
}
}
}
System.out.println(max);
I came up with below solution where i am using one array list, and following one formula:
divisor(a or b) X quotient(b or a) = dividend(c)
Sort the array.
Put array into Collection Col.(ex. which has faster lookup, and maintains insertion order)
Have 2 pointer a,c.
keep c at last, and a at 0.
try to follow (divisor(a or b) X quotient(b or a) = dividend(c)).
Check if a is divisor of c, if yes then check for b in col.(a
If a is divisor and list has b, then c is the answer.
else increase a by 1, follow step 5, 6 till c-1.
if max not found then decrease c index, and follow the steps 4 and 5.
Check this C# solution:
-Loop through each element,
-loop and multiply each element with other elements,
-verify if the product exists in the array and is the max
private static int GetGreatest(int[] input)
{
int max = 0;
int p = 0; //product of pairs
//loop through the input array
for (int i = 0; i < input.Length; i++)
{
for (int j = i + 1; j < input.Length; j++)
{
p = input[i] * input[j];
if (p > max && Array.IndexOf(input, p) != -1)
{
max = p;
}
}
}
return max;
}
Time complexity O(n^2)
UINT itemLength = strValue.length();
bRet = ( ( itemLength > maxLength ) || ( itemLength < minLength ) ) ? VARIANT_FALSE : VARIANT_TRUE;
This code is being used for Length validation.
I want to validate number:
For Ex:
min value = 0, Max value =10, original value = 5
In this condition i want to check only whole number.
For Ex, I want to display following:
Input -> Output
5 -> True
5.1 -> False i want to display.
assuming f as precision number try this
if (f % (int)f > 0)
{
Console.WriteLine("is not whole number");
}
else
{
Console.WriteLine("is whole number");
}
My assignment was to use the reference-based implementation of the ADT List and the array-based implementation of the ADT Stack in a program that has a user enter a string of lower-case letters. I was to go through the string and store each letter in both the list and the stack and then use the stack and list contents to determine if the string is a palindrome or not. I am to display the original sequence of letters, the sequence of letters in reverse order, and finally, a statement whether or not it is a palindrome or not. For some reason, when I input a palindrome, ex. madamimadam, it outputs that it is not a palindrome. I cannot figure out why, please help! Here is my code for the method:
import javax.swing.JOptionPane;
public class PalindromeTester
{
public static void main (String [] args)
{
Character ch;
boolean isPalindrome = true;
LinkedList myList = new LinkedList();
StackArrayBased myStack = new StackArrayBased();
String response = JOptionPane.showInputDialog ("Please enter a string of lower-case letters" ) ;
for ( int i = 0 ; i < response.length ( ) ; i++ )
{
ch = new Character ( response.charAt ( i ) ) ;
myStack.push ( ch ) ;
myList.add ( i + 1 , ch ) ;
}
System.out.println ( "The original sequence of characters is: " + response ) ;
System.out.print ( "The sequence of letters backwards is: " ) ;
int j = 1 ;
while ( ! myStack.isEmpty ( ) )
{
System.out.print ( myStack.peek ( ) ) ;
if ( ! myList.get ( j ).equals( myStack.pop ( ) ) ) ;
isPalindrome = false ;
}
if ( isPalindrome )
System.out.println ( "\nThe string is a palindrome." ) ;
else
System.out.println ( "\nThe string is not a palindrome." ) ;
}
}
Here is the ADT Stack class:
public class StackArrayBased
{
private static final int MAX_STACK = 15 ;
private Object items [ ] ;
private int top ;
public StackArrayBased ( )
{
items = new Object [ MAX_STACK ] ;
top = -1 ;
}
public boolean isEmpty ( )
{
return top < 0 ;
}
public boolean isFull ( )
{
return top == MAX_STACK - 1 ;
}
public void push ( Object newItem ) throws StackException
{
if ( ! isFull ( ) )
items [ ++ top ] = newItem ;
else
throw new StackException ( "StackException on push: stack is full" ) ;
}
public void popAll ( )
{
items = new Object [ MAX_STACK ] ;
top = -1 ;
}
public Object pop ( ) throws StackException
{
if ( ! isEmpty ( ) )
return items [ top -- ] ;
else
throw new StackException ( "StackException on pop: stack is empty" ) ;
}
public Object peek ( ) throws StackException
{
if ( ! isEmpty ( ) )
return items [ top ] ;
else
throw new StackException ( "StackException on peek: stack is empty" ) ;
}
}
and here is the ADT list:
public class LinkedList
{
private Node head;
private int numItems;
public LinkedList ( )
{
head = null ;
numItems = 0 ;
}
public boolean isEmpty ( )
{
return numItems == 0 ;
}
public int size ( )
{
return numItems ;
}
private Node find ( int position )
{
Node curr = head ;
for ( int i = 1 ; i < position ; i ++ )
curr = curr.getNext ( ) ;
return curr ;
}
public Object get ( int position )
{
if ( position >= 0 && position <= numItems )
{
Node curr = find ( position ) ;
Object dataItem = curr.getItem ( ) ;
return dataItem ;
}
else
{
System.out.println ( "Error in position value during get attempt." ) ;
return null ;
}
}
public void add ( int position, Object item )
{
if ( position >= 1 && position <= numItems + 1 )
{
if ( position == 1 )
{
Node newNode = new Node ( item, head ) ;
head = newNode ;
}
else
{
Node prev = find ( position - 1 ) ;
Node newNode = new Node ( item, prev.getNext ( ) ) ;
prev.setNext ( newNode ) ;
}
numItems ++ ;
}
else
System.out.println ( "Position is invalid on attempted add." ) ;
}
public void remove ( int position )
{
if ( position >= 1 && position <= numItems )
{
if ( position == 1 )
head = head.getNext ( ) ;
else
{
Node prev = find ( position - 1 ) ;
Node curr = prev.getNext ( ) ;
prev.setNext ( curr.getNext ( ) ) ;
}
numItems -- ;
}
else
System.out.println ( "Position is invalid on attempted remove." ) ;
}
public void removeAll ( )
{
head = null ;
numItems = 0 ;
}
}
If you want to set isPalindrome correctly, shouldn't you be doing something with j in this loop...?:
[...]
int j = 1 ;
while ( ! myStack.isEmpty ( ) )
{
System.out.print ( myStack.peek ( ) ) ;
if ( ! myList.get ( j ).equals( myStack.pop ( ) ) ) ;
isPalindrome = false ;
}
[...]
In the second loop, you should be incrementing j. Since linkedlist index can be 0, you shouldn't be doing i+1 index while adding ( in the first loop). If you make it a 0 based index you should be initalizing j to be 0 before the second loop.
The assignment seems odd; if you can access the last element of the list (as an abstract list allows in most language), then you can just do the for i=[0,length) {if input[i]!=input[length-1-i], return false} return true
And if you just had stacks to play with, you could just clone and reverse the stack (e.g. by pushing onto two stacks, and popping one of those into a new stack, thereby reversing it), and do the same thing as the for loop (go through the two stacks element-by-element to see if they're the same).
In both of the above linear-time algorithms (either the one that uses just lists, or the one that uses just stacks), the function should just be 3 lines or so.
I like the scruffy paper effect of http://yuml.me UML diagrams, is there an algorithm for that preferably not in Ruby but in PHP, java or C#, I would like to see if It's easy to do the same thing in Rebol:
http://reboltutorial.com/blog/easy-yuml-dialect-for-mere-mortals2/
The effect combines
a diagonal gradient fill
a drop shadow
lines which, rather than being straight, have some small apparently random deviations in them, which gives a 'scruffy' feel.
You can seed your random number generator with a hash of the input so you get the same image each time.
This seems to work OK for scruffing up lines:
public class ScruffyLines {
static final double WOBBLE_SIZE = 0.5;
static final double WOBBLE_INTERVAL = 16.0;
Random random;
ScruffyLines ( long seed ) {
random = new Random(seed);
}
public Point2D.Double[] scruffUpPolygon ( Point2D.Double[] polygon ) {
ArrayList<Point2D.Double> points = new ArrayList<Point2D.Double>();
Point2D.Double prev = polygon[0];
points.add ( prev ); // no wobble on first point
for ( int index = 1; index < polygon.length; ++index ) {
final Point2D.Double point = polygon[index];
final double dist = prev.distance ( point );
// interpolate between prev and current point if they are more
// than a certain distance apart, adding in extra points to make
// longer lines wobbly
if ( dist > WOBBLE_INTERVAL ) {
int stepCount = ( int ) Math.floor ( dist / WOBBLE_INTERVAL );
double step = dist / stepCount;
double x = prev.x;
double y = prev.y;
double dx = ( point.x - prev.x ) / stepCount;
double dy = ( point.y - prev.y ) / stepCount;
for ( int count = 1; count < stepCount; ++count ) {
x += dx;
y += dy;
points.add ( perturb ( x, y ) );
}
}
points.add ( perturb ( point.x, point.y ) );
prev = point;
}
return points.toArray ( new Point2D.Double[ points.size() ] );
}
Point2D.Double perturb ( double x, double y ) {
return new Point2D.Double (
x + random.nextGaussian() * WOBBLE_SIZE,
y + random.nextGaussian() * WOBBLE_SIZE );
}
}
example scruffed up rectangle http://img34.imageshack.us/img34/4743/screenshotgh.png