Problem statement
Construct a binary expression using infix expression. The infix expression uses extra parenthesis to enforce the priority of operators.
For example, infix expression ((1+2)+3)
can be expressed in a binary expression tree in the following:
+
/ \
+ 3
/ \
1 2
Write down your assumptions in your code. Sometimes comment is also helpful for people to evaluate how good you are in terms of problem solving skills.
My introduction
It is very good algorithm to learn to use stack to parse the expression, even though it is not straightforward. In order to get optimal time complexity, linear time by scanning the infix expression once, using data structure stack.
The challenge is to write a solution in less than 30 minutes, and also show good design of object-oriented programming.
The infix expression is enforced to use extra open and close parenthesis. For example, (1 + 2)
should be valid expression and then char '('
defines the start of a new expression. One idea is to linear scan the expression, push '('
into stack, and then '1'
into stack, and then '+'
into stack, '2'
into stack, and then once ')'
is visited, then pop up stack for 2 operands one operator and one '('
char to construct a binary tree using operator as the root.
Here is my C# code, please help me to review my solution.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace infixExpressionToBinaryExpressionTree
{
class Program
{
internal class Node
{
public char Operand { get; set; } // operator sometimes;
public Node Left;
public Node Right;
public Node(char val)
{
Operand = val;
}
}
static void Main(string[] args)
{
//RunTestcase1();
RunTestcase2();
}
public static void RunTestcase1()
{
var node = InfixExpressionToBinaryExpressionTree("(1+2)");
Debug.Assert(node.Operand == '+');
}
public static void RunTestcase2()
{
var node = InfixExpressionToBinaryExpressionTree("((1+2)*(3-4))");
Debug.Assert(node.Operand.CompareTo("*") == 0);
}
public static string Operators = "+-*/";
public static string Operands = "0123456789"; // make it simple, one digit only first
/// <summary>
/// Time complexity: O(N), space complexity: using stack -> at most O(N)
/// </summary>
/// <param name="expression"></param>
/// <returns></returns>
public static Node InfixExpressionToBinaryExpressionTree(string expression)
{
if (expression == null || expression.Length == 0)
return null;
var stack = new Stack<Object>();
for (int i = 0; i < expression.Length; i++)
{
var current = expression[i];
var isCloseBracket = current == ')';
if (!isCloseBracket)
{
stack.Push(current);
}
else
{
if (stack.Count < 4)
return null;
var operand2 = stack.Pop();
var operatorChar = stack.Pop();
var operand1 = stack.Pop();
var openBracket = (char)stack.Pop();
if (openBracket != '(' ||
!checkOperand(operand2) ||
!checkOperand(operand1) ||
!checkOperator(operatorChar)
)
{
return null;
}
var root = new Node((char)operatorChar);
root.Left = (operand1.GetType() == typeof(Node)) ? (Node)operand1 : new Node((char)operand1);
root.Right = (operand2.GetType() == typeof(Node)) ? (Node)operand2 : new Node((char)operand2);
stack.Push(root);
}
}
if (stack.Count > 1 || stack.Count == 0)
return null;
return (Node)stack.Pop();
}
/// <summary>
/// code review July 6, 2018
/// </summary>
/// <param name="operand"></param>
/// <returns></returns>
private static bool checkOperand(Object operand)
{
if (operand.GetType() == typeof(Node))
return true;
var number = (char)operand;
return Operands.IndexOf(number) != -1;
}
private static bool checkOperator(Object operatorChar)
{
var arithmetic = (char)operatorChar;
return Operators.IndexOf(arithmetic) != -1;
}
}
}
1
,(1)
,1+2
,( 1 + 2 )
,(1+2+3)
,(12+34)
, and so on. What exactly is the purpose of this exercise? \$\endgroup\$