Description: In this assignment, you will design and implement a service to eval
ID: 3872809 • Letter: D
Question
Description:
In this assignment, you will design and implement a service to evaluate arithmetic expressions, as well as a testing client.
Protocol Spec
Request format
1. Number of expressions to evaluate. [2 bytes]
2. Length of 1st expression in bytes. [2 bytes]
3. String representation of 1st expression.
4. Length of 2nd expression in bytes. [2 bytes]
5. String representation of 2nd expression.
6. …
7. Length of nth expression in bytes. [2 bytes]
8. String representation of nth expression.
Response format
1. Number of answers. [2 bytes]
2. Length of 1st answer in bytes. [2 bytes]
3. String representation of 1st answer.
4. Length of 2nd answer in bytes. [2 bytes]
5. String representation of 2nd answer.
6. …
7. Length of nth answer in bytes. [2 bytes]
8. String representation of nth answer.
Requirements
1. All numbers in expressions are integers.
2. Required to handle ‘+’, ‘-’, ‘*’, ‘/’. Optional for parenthesis.
3. Don’t use ‘eval’ in Python.
4. Use TCP as transport layer protocol.
5. Implement both server and client (server needs to be multithreaded).
6. Limit your buffer size for send/recv API to 16 bytes. (So you need to have axillary function to call recv multiple times to make sure entire request/response is received).
Example request 2 4 "3+12" 2 bytes 2 bytes 4 bytes 2 bytes 6 bytes Example response 2 2 "15" 1 5 2 bytes 2 bytes 2 bytes 2 bytes byteExplanation / Answer
ANSWER::
import java.util.Stack;
public class EvaluateString
{
public static int evaluate(String expression)
{
char[] tokens = expression.toCharArray();
Stack<Integer> values = new Stack<Integer>();
Stack<Character> ops = new Stack<Character>();
for (int i = 0; i < tokens.length; i++)
{
if (tokens[i] == ' ')
continue;
if (tokens[i] >= '0' && tokens[i] <= '9')
{
StringBuffer sbuf = new StringBuffer();
while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
sbuf.append(tokens[i++]);
values.push(Integer.parseInt(sbuf.toString()));
}
else if (tokens[i] == '(')
ops.push(tokens[i]);
else if (tokens[i] == ')')
{
while (ops.peek() != '(')
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.pop();
}
else if (tokens[i] == '+' || tokens[i] == '-' ||
tokens[i] == '*' || tokens[i] == '/')
{
while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
ops.push(tokens[i]);
}
}
while (!ops.empty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
return values.pop();
}
public static boolean hasPrecedence(char op1, char op2)
{
if (op2 == '(' || op2 == ')')
return false;
if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
return false;
else
return true;
}
public static int applyOp(char op, int b, int a)
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
if (b == 0)
throw new
UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
public static void main(String[] args)
{
System.out.println(EvaluateString.evaluate("10 + 2 * 6"));
System.out.println(EvaluateString.evaluate("100 * 2 + 12"));
System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 )"));
System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 ) / 14"));
}
}