I am trying to write 2 methods that can sort a string of brackets using only 1 stack and 1 switch statement. I can't get it to work, I am wondering if it may be because of cases of ' ' in strings? should not default case pick up these or have I understood switch statements wrong? This is where I am right now.
out.println(checkParentheses("({} [()] ({}))")); // should print true
out.println(!checkParentheses("({} [() ({)})")); // should print false
Boolean checkParentheses(String brackets) {
Deque<Character> stack = new ArrayDeque<>();
for( char ch : brackets.toCharArray()) {
if (stack.peek() == matching(ch)) {
stack.pop();
} else {
stack.add(ch);
}
}
return stack.isEmpty();
}
char matching(char ch) {
// char c = (' ');
switch (ch) {
case ')':
return '('; // c = '('
case ']':
return '[';
case '}':
return '{';
default:
// return c;
throw new IllegalArgumentException("No match found");
}
}
Non-bracket characters should be ignored in the input, optionally the input may be cleaned out of them or just skipped quietly
Special checks for opening/closing brackets need to be implemented.
Basically, checkParentheses should be as simple as follows:
public static boolean checkParentheses(String str) {
if (null == str || str.isEmpty()) {
return true;
}
Deque<Character> stack = new ArrayDeque<>();
for (char c : str.toCharArray()) {
if (openingBracket(c)) {
stack.push(c);
} else if (closingBracket(c)) {
if (stack.isEmpty() || matchingBracket(c) != stack.pop()) {
return false;
}
} // else ignore non-bracket char quietly
}
return stack.isEmpty();
}
Then additional methods may look as follows using switch statement:
static boolean openingBracket(char c) {
switch (c) {
case '(': case '[': case '{': case '<':
return true;
default:
return false;
}
}
static boolean closingBracket(char c) {
switch (c) {
case ')': case ']': case '}': case '>':
return true;
default:
return false;
}
}
static char matchingBracket(char c) {
switch (c) {
case ')': return '(';
case ']': return '[';
case '}': return '{';
case '>': return '<';
default:
throw new IllegalArgumentException("Bad character found instead of closing bracket: " + c);
}
}
Then the output of the tests is as follows:
System.out.println(checkParentheses("({} [()] ({}))")); // true, balance ok
System.out.println(!checkParentheses("({} [() ({)})")); // true, NOT balanced
Related
Hey everyone I need assistance with my java assignment, this is the assignment:
https://i.stack.imgur.com/kU2dj.png
https://i.stack.imgur.com/lmCxI.png
And I have attached my code as well. Can someone Help me out,
I do not know why I am getting errors. The code is not compiling as well. Please let me know what I can do, thank you:) !
package APackage;
import java.io.FileReader;
import java.io.BufferedReader;
public class MyPreprocessor
{
//MAIN METHOD
public static void main (String [] args)
{
//FileReader AND BuffeRedreader TO READ FROM FILE
FileReader fk = new FileReader("tet.txt");
BufferedReader bk = new BufferedReader(fk);
Preprocessor p;
String preLine;
//READING FROM FILE
while((preLine=br.readLine(bk))!=null)
{
//DISPLAY THE STRING AS WELL AS CHECK ITS BALANCED DELIMITERS
System.out.println("Line is: "+preLine +" is Balanced?"+balance_Chek(preLine));
}
}
}
This is the second required class called Preprocessor
package APackage;
import java.util.Stack;
import java.util.*;
import java.io.*;
class Preprocessor
{
public static boolean balance_Chek(String inStr12)
{
Stack<Character> s_st1 = new Stack<Character>();
for(int k1 = 0; k1 < inStr12.length(); k1++)
{
char let = inStr12.charAt(k1);
if(let == '[' || let == '{' || let == '('||let=='/')
{
switch(let)
{
// FORSQUARE BRACKET
case '[':
s_st1.push(let);
break;
// FOR CURLY BRACE
case '{':
s_st1.push(let);
break;
// FOR BRACKETS
case '(':
s_st1.push(let);;
break;
//FOR COMMANDS
case '/':
char t=inStr12.charAt(k1+1);
if(t=='*')
s_st1.push(let);
break;
default:
break;
}
}
else if(let == ']' || let == '}' || let == ')'||let=='*')
{
if(s_st1.empty())
return false;
switch(let)
{
// FORSQUARE BRACKET
case ']':
if (s_st1.pop() != '[')
return false;
break;
// FOR CURLY BRACE
case '}':
if (s_st1.pop() != '{')
return false;
break;
// FOR BRACKETS
case ')':
if (s_st1.pop() != '(')
return false;
break;
//FOR COMMANDS
case '*':
if(inStr12.charAt(k1+1)=='/')
if (s_st1.pop() != '/')
return false;
break;
default:
break;
}
}
}
if(s_st1.empty())//CHECK STACK IS EMPTY
return true;
return false;
}//EMD METHOD
}
The problem is after scanning the file called "confused.dat" it outputs 90% of what it is supposed to and the other 10% are incorrect.
I have tried exchanging methods of scanning the file but nothing really changed.
import java.util.Scanner;
import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;
public class confused {
public static boolean isBalanced(String inp) {
if ((inp.length() % 2) == 1){ return false;}
else {
Stack<Character> s = new Stack<>();
for (char brackBrick : inp.toCharArray())
switch (brackBrick) {
case '{': s.push('}'); break;
case '(': s.push(')'); break;
case '[': s.push(']'); break;
default : if (s.isEmpty() || brackBrick != s.peek()) { return false;}
s.pop();
}
return s.isEmpty();
}
}
public static void main(String[] args) /*throws FileNotFoundException*/ {
try{
Scanner scrn = new Scanner (new File("confused.dat"));
while (scrn.hasNextLine()){
boolean answer = isBalanced(scrn.nextLine());
if (answer) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
} catch (FileNotFoundException e){e.printStackTrace();}
}
}
confused.dat file:
([])
(([()])))
([()[]()])()
(([()])
([] )
(([()])))
([()[]()])()
(
(]
)(
][
Here is expected output vs. the actual output
https://imgur.com/cciHkGL
shouldn't it be a no, because
if ((inp.length() % 2) == 1){ return false;}
if (answer) {
System.out.println("Yes");
} else {
System.out.println("No");
(([()]))) is not a even number, so therefore it false, and thus will print no.
Oh, I think I got it. You were actually pretty close. First off, drop this line
if ((inp.length() % 2) == 1){ return false;}
and then ignore empty spaces by adding the following condition in your switch statement:
case ' ': break;
So all in all the updated method now looks like this
public static boolean isBalanced(String inp) {
Stack<Character> s = new Stack<>();
for (char brackBrick : inp.toCharArray()) {
switch (brackBrick) {
case '{': s.push('}'); break;
case '(': s.push(')'); break;
case '[': s.push(']'); break;
case ' ': break;
default : if (s.isEmpty() || brackBrick != s.peek()) { return false;}
s.pop();
}
}
return s.isEmpty();
}
You should now get the following output
Yes
Yes
No
Yes
No
Yes
No
Yes
No
No
No
No
I am trying to parse a string with both negative numbers and minus signs and add each token to a queue called infix and a function to tell if the token is an operator. However the negative gets treated like a minus sign and is added to queue separate from the negative number. Here is my code to break the string into numbers and add them to a queue.
for(int i = 0;i < expression.length();i++) // add all items from the expression to the infix queue
{
String value = String.valueOf(expression.charAt(i));
if(eval.isOperator(value) == true)
{
infix.add(value);
}
else
{
for(int j = i+1; eval.isOperator(String.valueOf(expression.charAt(j))) == false; j++)//add token to value until an operator is found and that number ends
{
value += expression.charAt(j);
i++;
}
infix.add(value);
}
}
and the eval class
public class Eval
{
public boolean isOperator(String n)
{
switch(n)
{
case "(":
return true;
case ")":
return true;
case "*":
return true;
case "/":
return true;
case "+":
return true;
case "-":
return true;
case "#":
return true;
}
return false;
}
public int Priority(String op)
{
switch(op)
{
case "(":
return 3;
case "*":
return 2;
case "/":
return 2;
case "+":
return 1;
case "-":
return 1;
}
return 0;
}
}
}
The way most languages handle this is by doing it later. As #Sweeper said, - would be an operator, and later code would select whether this is a binary or unary operator. Assuming you plan to evaluate these expressions at some point, doing it this way would really not be much extra work in the end.
To handle it your way, though, I would first extract some function, perhaps eval.lexNumber(String expression, int index) from your loop here
for(int j = i+1; eval.isOperator(String.valueOf(expression.charAt(j))) == false; j++)
Then it's just a matter of an explicit check:
if (value == "-" && isNumber(expression.charAt(j+1))
{
// I assume you have access to some sort of isNumber function
// and that you can check for an out of bounds access on your own
infix.add("-" + lexNumber(expression, j+1));
}
else if(eval.isOperator(value) == true)
{
infix.add(value);
}
else
{
// etc
}
This is a rough, untested push in the right direction that overlooks small problems. In particular, the problem of updating the loop index. I suggest some new class to encapsulate the expression source along with the current position. Something like:
while (tokenStream.hasNext())
{
infix.add(tokenStream.next());
}
public class Eval
{
boolean binaryOp = false;
public boolean isOperator(String n)
{
switch(n)
{
case "(":
return true;
case ")":
return true;
case "*":
;
case "/":
;
case "+":
binaryOp = true;
return true;
case "-":
If (binaryOp) break;
case "#":
return true;
}
binaryOp = false;
return false;
}
public int Priority(String op)
{
switch(op)
{
case "(":
return 3;
case "*":
return 2;
case "/":
return 2;
case "+":
return 1;
case "-":
return 1;
}
return 0;
}
}
I am writing a program where I should check if the opening parenthesis matches the closing one. If it doesn't match, I should display No. Otherwise, I should display yes.
This is the function I wrote, taking the input from the input buffer. However, I just keep on receiving yes for the second test case, instead of YES NO YES but the other two cases are correct.
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String[] answer = new String[values.length];
for(int i =0; i<values.length;i++){
char[] crt = values[i].toCharArray();
for(char c : crt){
switch(c){
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
if(st.isEmpty() || (st.peek() != '{'))
{
answer[i]= "NO";
break;
}
st.pop();
case ')':
if(st.isEmpty() || (st.peek() != '('))
{
answer[i]= "NO";
break;
}
st.pop();
case ']':
if(st.isEmpty() || (st.peek() != '['))
{
answer[i]= "NO";
break;
}
st.pop();
}
}
if(st.isEmpty() && answer[i].equals("NO") ){
answer[i]="YES";
System.out.println("I set answer[" + i + "] = YES due to stack being empty");
}
else
{
answer[i]="NO";
System.out.println("I set answer[" + i + "] = NO due to stack being non-empty");
}
st.clear();
}
return answer;
}
Change stack.firstElement() to stack.peek(), you need the stack top instead of the first element. (firstElement is not a Stack method)
The great secret of StackOverflow is that it's not actually full of gurus who look at your code the way Neo looks at The Matrix. It's just people examining how your programs runs.
You can do this yourself, and the most ancient and trivial way is through so-called "print debugging".
In short, you just add print statements that prints what your code is doing, and then you follow along and compare it to what you think it should be doing. Here's your code with such print statements added:
import java.util.*;
public class Test {
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String[] answer = new String[values.length];
for(int i =0; i<values.length;i++){
char[] crt = values[i].toCharArray();
boolean an = false;
for(char c : crt){
switch(c){
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
if(st.isEmpty() || (st.firstElement() != '{'))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched }");
}
st.pop();
break;
case ')':
if(st.isEmpty() || (st.firstElement() != '('))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched )");
}
st.pop();
break;
case ']':
if(st.isEmpty() || (st.firstElement() != '['))
{
answer[i]= "NO";
System.out.println("I set answer[" + i + "] = NO due to mismatched ]");
}
st.pop();
break;
}
}
if(st.isEmpty()){
answer[i]="yes";
System.out.println("I set answer[" + i + "] = YES due to stack being empty");
}
else
{
answer[i]="no";
System.out.println("I set answer[" + i + "] = NO due to stack being non-empty");
}
st.clear();
}
return answer;
}
public static void main(String[] args) {
String[] result = braces(new String[] { "(foo}" });
for(String s : result) System.out.println("The final result is " + s);
}
}
And here's the output, running on the string (foo}:
I set answer[0] = NO due to mismatched }
I set answer[0] = YES due to stack being empty
The final result is yes
Welp, it looks like you're overwriting your previous answer. You should make sure the final test doesn't override the loop's conclusion.
The trivial hack would be to check if answer[i] is null, but the better way would be to create a second helper method boolean braces(String) that is free to return true or false at any time, and then simply call that function in a loop in your braces(String[])
In any case, this would have been my implementation:
import java.util.Stack;
class Test {
static char flip(char c) {
switch(c) {
case '}': return '{';
case ')': return '(';
case ']': return '[';
default: throw new IllegalArgumentException("Invalid paren " + c);
}
}
static boolean matched(String value) {
Stack<Character> st = new Stack<Character>();
for (int i=0; i<value.length(); i++) {
char c = value.charAt(i);
switch(c) {
case '{':
case '(':
case '[':
st.push(c);
break;
case '}':
case ')':
case ']':
if (st.isEmpty() || st.peek() != flip(c)) {
return false;
}
st.pop();
break;
}
}
return st.isEmpty();
}
static String[] braces(String[] values) {
String[] result = new String[values.length];
for(int i=0; i<result.length; i++) {
result[i] = matched(values[i]) ? "yes" : "no";
}
return result;
}
public static void main(String[] args) {
String[] input = new String[] { "}", "{}", "{()}", "asdf", "", "{[", "{[[([])]]}", "((foo))" };
String[] actual = braces(input);
String[] expected = new String[] { "no", "yes", "yes", "yes", "yes", "no", "yes", "yes" };
for(int i=0; i<actual.length; i++) {
if(!actual[i].equals(expected[i])) {
System.out.println("Failed: " + input[i] + " should have been " + expected[i]);
System.exit(1);
}
}
System.out.println("OK");
}
}
import java.util.*;
import java.util.stream.Collectors;
public class Test {
static final Map<Character, Character> PARENS;
static final Set<Character> CLOSING_PARENS;
static {
PARENS = new HashMap<>();
PARENS.put('{', '}');
PARENS.put('[', ']');
PARENS.put('(', ')');
CLOSING_PARENS = new HashSet<>(PARENS.values());
}
public static void main(String[] args) {
print(braces("(foo}","[]","()","{}","[{}]","([{}])","[[]]"));
print(braces("[","]","][","[{]}"));
// test case 2 ...
print(braces("{[()]}","{[(])}","{{[[(())]]}}"));
// ... prints YES NO YES ...
}
static void print(String ... values){
for(String str : values){
System.out.print(str + " ");
}
System.out.println();
}
static String [] braces(String ... values) {
return Arrays.stream(values)
.map(Test::isBalanced)
.map(b -> b ? "YES" : "NO")
.collect(Collectors.toList()).toArray(new String[values.length]);
}
static boolean isBalanced(String token){
Stack<Character> stack = new Stack<>();
for(char c : token.toCharArray()){
if (PARENS.keySet().contains(c)){
stack.push(c);
} else if(CLOSING_PARENS.contains(c)){
if(stack.isEmpty() || !PARENS.get(stack.pop()).equals(c)) {
return false;
}
}
}
return stack.isEmpty();
}
}
you just have to make the following changes
Replace firstElement() with peek() in all cases
remove the following statement from the first two cases
stack.pop();
break;
check if stack is empity at the last case
if(!stack.isEmpty())
corrected code:
public class ParenMatch{
public static void main(String[] args){
String[] str = { "{}[](){[}]","{[()]}{[(])}{{[[(())]]}}","", "}][}}(}][))][](){()}()({}([][]))[](){)[](}]}]}))}(())(([[)"};
System.out.println(Arrays.toString(braces(str)));
}
public static String[] braces(String[] values)
{
Stack<Character> stack = new Stack<Character>();
String[] isCorrect = new String[values.length];
for (int i = 0; i < values.length; i++)
{
char[] crt = values[i].toCharArray();
boolean an = false;
for (char c : crt)
{
switch(c)
{
case '{':
case '(':
case '[':
stack.push(c);
break;
case '}':
if (stack.isEmpty() || (stack.peek() != '{'))
{
isCorrect[i] = "NO";
}
//stack.pop();
//break;
case ')':
if (stack.isEmpty() || (stack.peek() != '('))
{
isCorrect[i] = "NO";
}
//stack.pop();
//break;
case ']':
if (stack.isEmpty() || (stack.peek() != '['))
{
isCorrect[i] = "NO";
}
if(!stack.isEmpty())
stack.pop();
break;
}
}
if (stack.isEmpty())
{
isCorrect[i] = "yes";
}
else
{
isCorrect[i] = "no";
}
stack.clear();
}
return isCorrect;
}
}
input:
String[] str = { "{}[](){[}]","{[()]}{[(])}{{[[(())]]}}","", "}][}}(}][))][](){()}()({}([][]))[](){)[](}]}]}))}(())(([[)"};
output:
[yes, yes, yes, no]
static String[] braces(String[] values) {
Stack<Character> st = new Stack<Character>();
String []answer = new String[values.length];
Boolean isCorrect = false;
for(int i =0; i< values.length;i++)
{
isCorrect = true;
st.clear();
char crt[] = values[i].toCharArray();
for(char c : crt)
{
switch(c)
{
case'{':
case'[':
case'(':
st.push(c);
break;
case'}':
if(st.isEmpty() || st.peek() != '{')
{
System.out.println("Hellooo");
answer[i] ="NO";
isCorrect = false;
}
if(!st.isEmpty())
{
st.pop();
}
break;
case']':
if(st.isEmpty() || st.peek() != '[')
{
System.out.println("Hell");
answer[i] ="NO";
isCorrect = false;
}
if(!st.isEmpty())
{
st.pop();
}
break;
case')':
if(st.isEmpty() || st.peek() != '(')
{
isCorrect = false;
}
if(!st.isEmpty()) {
st.pop();
}
break;
}
}
if(isCorrect && st.isEmpty())
{
answer[i] = "YES";
System.out.println("Hello");
}else answer[i] = "NO";
}
return answer;
}
I've created a stack calculator for my Java class to solve equations such as
2 + ( 2 * ( 10 – 4 ) / ( ( 4 * 2 / ( 3 + 4) ) + 2 ) – 9 )
2 + { 2 * ( 10 – 4 ) / [ { 4 * 2 / ( 3 + 4) } + 2 ] – 9 }
We are suppose to implement { } [ ] into our code. I did it with just parentheses. It works 100% with just ( ). When I try to add { } [ ], it goes bananas.
This is what I have so far:
package stackscalc;
import java.util.Scanner;
import java.util.Stack;
import java.util.EmptyStackException;
class Arithmetic {
int length;
Stack stk;
String exp, postfix;
Arithmetic(String s) {
stk = new Stack();
exp = s;
postfix = "";
length = exp.length();
}
boolean isBalance() {
boolean fail = false;
int index = 0;
try {
while (index < length) {
char ch = exp.charAt(index);
switch(ch) {
case ')':
stk.pop();
break;
case '(':
stk.push(new Character(ch));
break;
default:
break;
}
index++;
}
} catch (EmptyStackException e) {
fail = true;
}
return stk.empty() && !fail;
}
void postfixExpression() {
String token = "";
Scanner scan = new Scanner(exp);
stk.clear();
while(scan.hasNext()) {
token = scan.next();
char current = token.charAt(0);
if (isNumber(token)) {
postfix = postfix + token + " ";
} else if(isParentheses(current)) {
if (current == '(') {
stk.push(current);
} else {
Character ch = (Character) stk.peek();
char nextToken = ch.charValue();
while(nextToken != '(') {
postfix = postfix + stk.pop() + " ";
ch = (Character) stk.peek();
nextToken = ch.charValue();
}
stk.pop();
}
} else {
if (stk.empty()) {
stk.push(current);
} else {
Character ch = (Character) stk.peek();
char top = ch.charValue();
if (hasHigherPrecedence(top, current)) {
stk.push(current);
} else {
ch = (Character) stk.pop();
top = ch.charValue();
stk.push(current);
stk.push(top);
}
}
}
}
try {
Character ch = (Character) stk.peek();
char nextToken = ch.charValue();
while (isOperator(nextToken)) {
postfix = postfix + stk.pop() + " ";
ch = (Character) stk.peek();
nextToken = ch.charValue();
}
} catch (EmptyStackException e) {}
}
boolean isNumber(String s) {
try {
int Num = Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
void evaluateRPN() {
Scanner scan = new Scanner(postfix);
String token = "";
stk.clear();
while(scan.hasNext()) {
try {
token = scan.next();
if (isNumber(token)) {
stk.push(token);
} else {
char current = token.charAt(0);
double t1 = Double.parseDouble(stk.pop().toString());
double t2 = Double.parseDouble(stk.pop().toString());
double t3 = 0;
switch (current) {
case '+': {
t3 = t2 + t1;
stk.push(t3);
break;
}
case '-': {
t3 = t2 - t1;
stk.push(t3);
break;
}
case '*': {
t3 = t2 * t1;
stk.push(t3);
break;
}
case '/': {
t3 = t2 / t1;
stk.push(t3);
break;
}
default: {
System.out.println("Reverse Polish Notation was unable to be preformed.");
}
}
}
} catch (EmptyStackException e) {}
}
}
String getResult() {
return stk.toString();
}
int stackSize() {
return stk.size();
}
boolean isParentheses(char current) {
if ((current == '(') || (current == ')')) {
return true;
} else {
return false;
}
}
boolean isOperator(char ch) {
if ((ch == '-')) {
return true;
} else if ((ch == '+')) {
return true;
}
else if ((ch == '*')) {
return true;
}
else if((ch == '/')) {
return true;
} else {
}
return false;
}
boolean hasHigherPrecedence(char top, char current) {
boolean HigherPre = false;
switch (current) {
case '*':
HigherPre = true;
break;
case '/':
HigherPre = true;
break;
case '+':
if ((top == '*') || (top == '/') || (top == '-')) {
HigherPre = false;
} else {
HigherPre = true;
}
break;
case '-':
if ((top == '*') || (top == '/') || (top == '-')) {
HigherPre = false;
} else {
HigherPre = true;
}
break;
default:
System.out.println("Higher Precedence Unsuccessful was unable to be preformed.");
break;
}
return HigherPre;
}
String getPostfix() {
return postfix;
}
}
What I am assuming is that (), {}, and [] all have the same weight in terms of order of operations, and you just need to modify your code in order to allow for all three interchangeably.
If that is the case, I would just use the matcher class with a simple regex check to see if the current char that you are looking at is either a parenthesis, curly brace, or bracket.
//convert char to string
String temp += currentChar;
//this will check for (, [, and { (need escapes because of how regex works in java)
Pattern bracePattern = Pattern.compile("[\(\{\[]");
Matcher matcher = numPatt.matcher(temp);
if(matcher.find()){
//you know you have a grouping character
}
This code should allow you to find all the opening grouping characters (just substitute (,{, and [ for ),} and ] in the regex to find closing characters). This can be used in your isParenthesis() method.
You could use a method like this to streamline checking if a '(', '[', or '{' is matched or not.
static char getExpected(char val){
char expected=' ';
switch (val) {
case '(':
expected=')';
break;
case '[':
expected=']';
break;
case '{':
expected='}';
break;
}
return expected;
}