Java, check if string is JSON Using Stacks - java

public class JsonValidator {
public static boolean isValidJSON(String jsonString) {
Stack<Character> stack = new Stack<>();
for (char c : jsonString.toCharArray()) {
switch (c) {
case '{':
stack.push(c);
break;
case '}':
if (stack.isEmpty()) {
return false;
}
Character last1 = stack.pop();
if (last1 != '{') {
return false;
}
break;
case '[':
stack.push(c);
break;
case ']':
if (stack.isEmpty()) {
return false;
}
Character last2 = stack.pop();
if (last2 != '[') {
return false;
}
break;
case '\"':
if (stack.isEmpty()) {
return false;
}
Character last3 = stack.peek();
if (last3 == '\"') {
stack.pop();
} else {
stack.push(c);
}
stack.push(c);
}
}
return stack.isEmpty();
}
assertTrue(JsonValidator.isValidJSON(""{""), "The brackets and quotes are balanced, making this a valid JSON string");
This is one of my test cases, its supposed to be valid JSON but it keeps giving me false

The problem with your checker is that when you check "{" you are pushing characters onto the stack that are never going to be popped. Hence, the stack is not empty.
Hint: look carefully at what is being pushed and popped when you process a string.
Also, your parser is not dealing with escapes in strings at all. And a { or } or [ or ] encountered within a JSON string should be treated as regular data.

Related

infixToPostfix algorithm but without operation priority

If i have this string infix expression 2*4+3-15/2 and i want as output the postfix expression without considering the priority of the operations like so
2 4 * 3 + 15 - 2 /
What modifications do i need to in this code sample to "remove" that priority. I took this code from geeksforgeeks here https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/. I find it a little difficult to change to meet what i want. Where should i start? thanks.
the current code gives me this output : 24*3+152/-
private int Prec(String ch)
{
switch (ch)
{
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "^":
return 3;
}
return -1;
}
private boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
private String infixToPostfix(String infixExpression){
// initializing empty String for result
StringBuilder postfixExpression = new StringBuilder(new String(""));
String[] infixExp = infixExpression.split(" ");
// initializing empty stack
Stack<String> stack = new Stack<>();
for (String token : infixExp) {
System.out.println(token+" ");
// If the scanned character is an operand, add it to output.
if (isNumeric(token))
postfixExpression.append(token);
// If the scanned character is an '(', push it to the stack.
else if (token.equals("("))
stack.push(token);
// If the scanned character is an ')', pop and output from the stack
// until an '(' is encountered.
else if (token.equals(")")) {
while (!stack.isEmpty() && !stack.peek().equals("("))
postfixExpression.append(stack.pop());
if (!stack.isEmpty() && !stack.peek().equals("("))
return "Invalid Expression"; // invalid expression
else
stack.pop();
} else // an operator is encountered
{
while (!stack.isEmpty() && Prec(token) <= Prec(stack.peek())) {
if (stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
stack.push(token);
}
}
// pop all the operators from the stack
while (!stack.isEmpty()){
if(stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
System.out.println(postfixExpression);
return postfixExpression.toString();
}
It seems you just need to reverse the order of each pair formed by an operator and a number. You could do this using regular expressions and replaceAll:
String infix = "2*4+3-15/2";
String postfix = infix.replaceAll("([*+-/])([0-9]+)", " $2 $1");
System.out.println(postfix);
Output:
2 4 * 3 + 15 - 2 /

Why isn't .equals recognizing my variable as the same string that I'm passing it?

So this little function is supposed to check if parentheses and brackets are matched next to each other. I feel like it should work and I've tried it a few different ways but I can't figure out how to check if my next char is what I expect it to be.
class Parenths {
public boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i+=2) {
String curr= String.valueOf(parens[i]);
String next = String.valueOf(parens[i+1]);
// System.out.println(next.equals(")"); --------> false
// System.out.println(Object.equals(next, ")")); ----> error
switch (curr) {
case "(": if (!next.equals(")")) return false;
case "{": if (!next.equals("}")) return false;
case "[": if (!next.equals("]")) return false;
}
}
return true;
}
}
You can see the lines I printed to debug and it seems that .equals is not the right thing to use here? Can anyone explain why this isn't working?
PS. I realize I don't have to convert the string to a char array to compare elements, so unless that's the only fix, please don't point that out to me.
Not tested, but it seems to be a problem of fall through. Try to replace if (boolean) return boolean with return boolean, this should do the trick.
The problem is that you don't have a break at the end of the cases, so if, for example, your first case is true, it will not stop execution and execute the 2nd test, which will be false. If you change your conditional statements to a direct return, you will not have this problem.
EDIT: Sorry, I read too quickly. Doing so will break your loop. Actually, you have to add a break at the end of the cases.
case "(": if (!next.equals(")")) return false; break;
case "{": if (!next.equals("}")) return false; break;
case "[": if (!next.equals("]")) return false; break;
First , you have to add break; after the cases its important to stop seeing the cases
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
}
Secondly , your code doesnt support the confrotation of a closing patenthesis at first , you have to add a default case
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
Also , you have to make sure the next element is not null before comparing to it , and dont increment with 2 , you give a String with a one element and that's why you get the error
public static boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i++) {
String curr= String.valueOf(parens[i]);
String next = "";
try {
next = String.valueOf(parens[i+1]);
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
}catch(Exception e) {}
}
return false;
}
Test :
System.out.println(isValid("()"));
// Output : true
System.out.println(isValid("("));
// Output : false

Checking if parenthesis are balanced or not using Stack?

I have written a java code to test if an expression is balanced or not, that is, this program checks if the characters '(', '{' and '[' have a corresponding delimiter or not. However I am unable to get the required answer. There is something wrong and I am unable to figure it out and hence would need your help. Here is the code.
package z_Stack_InfixToPostfix;
import java.util.Stack;
public class Driver_InfixToPostfix {
public static void main(String[] args) {
String s="(a+b)";
System.out.println(checkBalance(s));
}
public static boolean checkBalance(String expression){
boolean isBalanced=true;
Stack<Character> myStack=new Stack<Character>();
int length=expression.length();
int i=0;
while(isBalanced && i<length){
switch(expression.charAt(i)){
case '(': case '{': case '[' :
myStack.push(expression.charAt(i));
break;
case ')': case '}': case ']':
if(myStack.isEmpty()){
isBalanced=false;
}
else{
char opendelimiter=myStack.pop();
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
}
break;
}
i++;
}
if(!myStack.isEmpty()){
isBalanced=false;
}
return isBalanced;
}
}
char opendelimiter=myStack.pop();
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
Here you should check
if(openedDeimilter == '('){
if(expression.charAt(i)!=')'){
isBalanced=false;
//break;
}
}else if(openedDeimilter == '['){
if(expression.charAt(i)!=']'){
isBalanced=false;
//break;
}
}else {
if(expression.charAt(i)!='}'){
isBalanced=false;
//break;
}
}
Also once isBalanced is set to false you can skip iterating the remaining string, if it suits you.
What about a different approach using only the length of your expression without each parentheses? This will let you not use the Stack class and should be more efficient for longer expression
public static boolean checkBalance(String expression) {
String[] parentheses = new String[]{"\\(|\\)","\\[|\\]","\\{|\\}"};
int length = expression.length();
for(int i=0; i<parentheses.length; i++) {
int newLength = expression.replaceAll(parentheses[i], "").length();
int diff = length - newLength;
if(diff % 2 != 0) {
return false;
}
}
return true;
}
The double backslash are used to escape each parentheses because they are special characters
This part is wrong:
if(opendelimiter!=expression.charAt(i)){
isBalanced=false;
}
You check if two chars are equal, but the correct check should match the 2 corresponding chars: [ - ], ( - ) and { - }
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char exp[1028];
char ext[1028];
int top = -1;
//-----------------------------------------------------------------------------
push(char x){
top++;
ext[top]=x;
}
//-----------------------------------------------------------------------------------------
void pop(){
top--;
}
//--------------------------------------------------------------------------------------
main()
{
int ans;
char in='{';
char it='[';
char ie='(';
char an;'}';
char at=']';
char ae=')';
printf("\nenter your expression\n");
gets(exp);
int j=strlen(exp);
int i;
for(i=0;i<=j;i++){
if(exp[i] == in || exp[i] == it || exp[i]==ie){
push(exp[i]);
}
if(exp[i] == an ||exp[i]== at || exp[i]==ae){
pop();
}
}
if(top == -1){
printf("\nexp is balanced\n");
}
else{
printf("\nexp is unbalanced");
}
}

Infix to Postfix Java Algorithm Issue

So I was assigned to create an method which takes in a string in infix notation as a parameter and returns a string in postfix notation.
My code seems to work for most examples I throw at it, but a few inputs cause wacky results.
public class Operations<T> {
public int value(char c){
switch(c){
case '(':
case ')':
return 3;
case '*':
case '/':
case '%':
return 2;
case '+':
case '-':
return 1;
default:
return 0;
}
}
public String infixToPostfix(String infix){
//Operator stack
myStack<Character> ops = new myStack<Character>();
//Postfix string
String postfix = "";
//Current char being read
char c;
//Marks if paranthesis are being passed in
boolean flag = false;
//Iterate through each character to find operators
for(int i=0; i<infix.length(); i++){
c = infix.charAt(i);
//Add operand to postfix and operator to stack
if(value(c)==0){
postfix+=c;
} else if(ops.isEmpty() || (value(c)>value(ops.getTop()) && c!=')') || c=='(') {
ops.push(c);
} else if(value(c)<value(ops.getTop()) && c!=')') {
if(ops.getTop()=='(' || flag) {
ops.push(c);
flag = true;
} else {
postfix+=ops.pop();
while(!ops.isEmpty() && value(c)<value(ops.getTop())) {
postfix+=ops.pop();
}
ops.push(c);
}
} else if(c==')') {
while(ops.getTop()!='('){
postfix+=ops.pop();
}
ops.pop();
flag = false;
} else {
postfix+=ops.pop();
ops.push(c);
}
}
while(!ops.isEmpty()){
postfix+=ops.pop();
}
return postfix;
}
}
for example, the equation:
- A * B + (C/D*7) – ( (A%C-8) / (H+F-D))
outputs:
ABCD/7+AC8-%HF+D-/-
while the correct answer is:
ABCD/7+AC%8-HF+D-/
What is causing the problem? Thanks

Infix to Postfix using Stacks Java

I am trying to write a program to convert an infix expression to a postfix expression.
The algorithm that I am using is as follows :
1. Create a stack
2. For each character t in the expression
- If t is an operand, append it to the output
- Else if t is ')',then pop from the stack till '(' is encountered and append
it to the output. do not append '(' to the output.
- If t is an operator or '('
-- If t has higher precedence than the top of the stack, then push t
on to the stack.
-- If t has lower precedence than top of the stack, then keep popping
from the stack and appending to the output until either stack is
empty or a lower priority operator is encountered.
After the input is over, keep popping and appending to the output until the
stack is empty.
Here is my code which prints out wrong results.
public class InfixToPostfix
{
private static boolean isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')';
}
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
case '+':
case '-':
return !(op2 == '+' || op2 == '-');
case '*':
case '/':
return op2 == '^' || op2 == '(';
case '^':
return op2 == '(';
case '(':
return true;
default:
return false;
}
}
public static String convertToPostfix(String infix)
{
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++)
{
c = infix.charAt(i);
if (!isOperator(c))
{
postfix.append(c);
}
else
{
if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
postfix.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else
{
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (pop != '(')
{
postfix.append(pop);
}
}
}
stack.push(c);
}
}
}
return postfix.toString();
}
public static void main(String[] args)
{
System.out.println(convertToPostfix("A*B-(C+D)+E"));
}
}
The program should print AB*CD+-E+ but it is printing AB*-CD+E.
Why is the output incorrect ?
Also, Is there a more elegant solution to this problem. Please share if you have or know one.
Issue is with your else part:
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (pop != '(')
{
postfix.append(pop);
}
}
}
stack.push(c);
So here you are pushing the same c element twice with stack.push() when you see stack is not empty and precedence match is higher.
So put this stack.push within else part or remove the push from if condition.
Another issue is, when at the end you have some operators within the stack you dont pop them out.
Here's the code that i came up with for your case:
private static boolean isOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
|| c == '(' || c == ')';
}
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
case '+':
case '-':
return !(op2 == '+' || op2 == '-');
case '*':
case '/':
return op2 == '^' || op2 == '(';
case '^':
return op2 == '(';
case '(':
return true;
default:
return false;
}
}
public static String convertToPostfix(String infix)
{
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++)
{
c = infix.charAt(i);
if (!isOperator(c))
{
postfix.append(c);
}
else
{
if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
postfix.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else
{
if (!stack.isEmpty() && !isLowerPrecedence(c, stack.peek()))
{
stack.push(c);
}
else
{
while (!stack.isEmpty() && isLowerPrecedence(c, stack.peek()))
{
Character pop = stack.pop();
if (c != '(')
{
postfix.append(pop);
} else {
c = pop;
}
}
stack.push(c);
}
}
}
}
while (!stack.isEmpty()) {
postfix.append(stack.pop());
}
return postfix.toString();
}
public static void main(String[] args)
{
System.out.println(convertToPostfix("A*B-(C+D)+E"));
}
I think above answer is not correct.
This is the version corrected by me :
package Stack;
import java.util.Stack;
/*
*
Algorithm
1. Scan the infix expression from left to right.
2. If the scanned character is an operand, output it.
3. Else,
…..3.1 If the precedence of the scanned operator is greater than the precedence of the operator in the stack(or the stack is empty), push it.
…..3.2 Else, Pop the operator from the stack until the precedence of the scanned operator is less-equal to the precedence of the operator residing on the top of the stack. Push the scanned operator to the stack.
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop and output from the stack until an ‘(‘ is encountered.
6. Repeat steps 2-6 until infix expression is scanned.
7. Pop and output from the stack until it is not empty.
*/
public class InfixToPostFixEvalution {
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')';
}
private static int getPrecedence(char ch) {
switch (ch) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
// A utility function to check if the given character is operand
private static boolean isOperand(char ch) {
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}
public static String convertToPostfix(String infix) {
Stack<Character> stack = new Stack<Character>();
StringBuffer postfix = new StringBuffer(infix.length());
char c;
for (int i = 0; i < infix.length(); i++) {
c = infix.charAt(i);
if (isOperand(c)) {
postfix.append(c);
} else if (c == '(') {
stack.push(c);
}
// If the scanned character is an ‘)’, pop and output from the stack
// until an ‘(‘ is encountered.
else if (c == ')') {
while (!stack.isEmpty() && stack.peek() != '(') {
postfix.append(stack.pop());
}
if (!stack.isEmpty() && stack.peek() != '(')
return null;
else if(!stack.isEmpty())
stack.pop();
}
else if (isOperator(c)) // operator encountered
{
if (!stack.isEmpty() && getPrecedence(c) <= getPrecedence(stack.peek())) {
postfix.append(stack.pop());
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
postfix.append(stack.pop());
}
return postfix.toString();
}
public static void main(String[] args) {
System.out.println(convertToPostfix("a+b*(c^d-e)^(f+g*h)-i"));
}
}
This code inserts the "(" as well in stack and removes accordingly. Just another way of implementing infix to postfix. Here the check is until I do not find lower priority operator in stack I will pop out the value. e.g if stack has - and next operator is +, it will pop - as it is of equal priority.
I have added custom stack implementation, however normal stack provide by java can also be used in place
import chapter4.LinkedListStack(custom stack implementation);
public class InfixToPostfix {
public String infixToPostfix(String str) {
LinkedListStack<String> stack = new LinkedListStack<>();
String[] st = str.split("");
String result = "";
for (String s : st) {
if (operator(s)) {
if (")".equals(s)) {
while (!stack.isEmpty() && !"(".equals(stack.getTop())) {
result += stack.pop();
}
if (!stack.isEmpty()) {
stack.pop();
}
} else {
if (!stack.isEmpty() && !isLowerPrecedence(s, stack.getTop())) {
stack.push(s);
} else {
while (!stack.isEmpty() && isLowerPrecedence(s, stack.getTop())) {
String top = stack.pop();
if (!"(".equals(top)) {
result += top;
}
}
stack.push(s);
}
}
} else {
result += s;
}
}
while (!stack.isEmpty()) {
result += stack.pop();
}
return result;
}
private boolean isLowerPrecedence(String s, String s1) {
switch (s) {
case "+":
return !("+".equals(s1) || "(".equals(s1));
case "-":
return !("-".equals(s1) || "(".equals(s1));
case "*":
return "/".equals(s1) || "^".equals(s1) || "(".equals(s1);
case "/":
return "*".equals(s1) || "^".equals(s1) || "(".equals(s1);
case "^":
return "(".equals(s1);
case "(":
return false;
default:
return false;
}
}
private boolean operator(String s) {
return "+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s) || "^".equals(s) || "(".equals(s) ||
")".equals(s);
}
public static void main(String[] args) {
InfixToPostfix itp = new InfixToPostfix();
System.out.println("The Postfix expression for A*B-(C+D)+E is: " + itp.infixToPostfix("A*B-(C+D)+E"));
System.out.println("The Postfix expression for 1+2*4/5-7+3/6 is: " + itp.infixToPostfix("1+2*4/5-7+3/6"));
System.out.println("The Postfix expression for a+(b*c)/d is: " + itp.infixToPostfix("a+(b*c)/d"));
}
}
public class LinkedListStack<E> {
private Node<E> head;
private static class Node<E> {
E item;
Node<E> next;
public Node(E item, Node<E> next) {
this.item = item;
this.next = next;
}
}
public void push(E item) {
System.out.println("push: " + item);
Node<E> newNode = new Node<>(item, null);
newNode.next = head;
head = newNode;
}
public E pop() {
if (isEmpty()) {
System.out.println("stack is Empty -> empty stack exception");
return null;
}
System.out.println("pop: " + head.item);
E data = head.item;
head = head.next;
return data;
}
public boolean isEmpty() {
return head == null;
}
public E getTop() {
return head.item;
}
}
I think the problem is here:
private static boolean isLowerPrecedence(char op1, char op2)
{
switch (op1)
{
.....
case '(':
return true;
.....
}
In the case '(', false should be returned.
This solution requires proper braces around the original expression, but its quite simple and straight forward compared to other answers I looked at. Just for someone who might need it because the post is an old post.
public static String InfixToPostfix(String origin)
{
String[] params = origin.split(" ");
Stack<String> ops = new Stack<>();
Stack<String> vals = new Stack<>();
for (int i = 0; i < params.length; i++)
{
switch (params[i]) {
case "(":
;
break;
case "+":
ops.push(params[i]);
break;
case "-":
ops.push(params[i]);
break;
case "*":
ops.push(params[i]);
break;
case "/":
ops.push(params[i]);
break;
case "sqrt":
ops.push(params[i]);
break;
// Token not operator or paren: push double value.
case ")":
String d1 = vals.pop();
String d2 = vals.pop();
String op = ops.pop();
vals.push("( " + d2 + " " + d1 + " "+ op + " )");
break;
default:
vals.push(params[i]);
break;
}
}
// System.out.print(vals.pop());
return vals.pop();
}

Categories

Resources