So i have an assignment to write infix to postfix method without any nested loops (loops in loops) and i didn't notice that and i wrote long method with nested loops, any idea how to fix it? here is the code
How can i divide them into smaller method while have stack?
List<String> infix2Postfix(List<String> infix) {
Stack<String> opStack = new Stack<>();
List<String> outPut = new ArrayList<>();
for (String inComing : infix) {
// When incoming is one of -,+,*,/,^
if (OPERATORS.contains(inComing)) {
if (opStack.empty() || opStack.peek().equals("(")) {
....
} else {
....
if (inComingP == 4 && inComingP == operatorP) {
....
} else if (inComingP == operatorP) {
...
} else if (inComingP < operatorP) {
while (!opStack.empty() && !opStack.peek().equals("(")) {
...
}
opStack.push(inComing);
} else {
opStack.push(inComing);
}
}
}
// when incoming is one of "(" , ")"
else if ("()".contains(inComing)) {
if (")".equals(inComing)) {
while (opStack.size() != 0 && !opStack.peek().equals("(")) {
...
}
if (opStack.size() == 0) {
...
} else {
opStack.pop();
}
} else {
opStack.add(inComing);
}
} else {
outPut.add(inComing);
}
}
if (opStack.contains("(")) {
throw new IllegalArgumentException(MISSING_OPERATOR);
}
while (!opStack.empty()) {
outPut.add(opStack.pop());
}
return outPut;
}
Related
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 6 years ago.
I am writing a code that will import a string of characters from a text file, analyze the string using a stack and determine which "language" the string belongs to based on whether or not it fits certain rules. The code below tests to see if an input follows the pattern (A^nB^)^p (where n is greater than or equal to 0). The way I have it written is to load the first set of A's and B's onto a stack, then load the second set of A's and B's onto another stack, pop the two stacks at the same time and compare the returned values. If they match, move on (until the two stacks empty at the same time, hopefully) if they don't then return false.
public static boolean checkL4(File file) throws IOException
{
Stack stack1 = new Stack();
Stack stack2 = new Stack();
Stack stack3 = new Stack();
boolean firstCompare = true;
boolean bStart = false;
char w = 0;
try (Scanner sc = new Scanner(file).useDelimiter("\\s*"))
{
while (sc.hasNext()){
w = sc.next().charAt(0);
if (w == 0) {
return true;
}
if (w != 'A' && w != 'B')
{
return false;
}
if (w == 'A') {
if(!bStart) {
stack1.push(w);
stack3.push(w);
}
if(bStart && stack2.isEmpty()) {
stack2.push(w);
} else {
if (firstCompare) {
while (!stack1.isEmpty() || !stack2.isEmpty()) {
if (!stack1.isEmpty() && stack2.isEmpty())
{
return true;
}
if (stack1.isEmpty() && !stack2.isEmpty()) {
return false;
} else {
if (stack1.pop() == stack2.pop()) {
return true;
} else {
return false;
}
}
}
stack1.push(w);
firstCompare = false;
} else {
if(stack1.isEmpty()){
while (!stack3.isEmpty() || !stack2.isEmpty()) {
if (stack3.isEmpty() && !stack2.isEmpty()) {
return false;
} else {
if (stack2.isEmpty() && !stack3.isEmpty()) {
return false;
} else {
if (stack3.pop() == stack2.pop()) {
return true;
} else {
return false;
}
}
}
}
stack1.push(w);
}
if (stack3.isEmpty()){
while (!stack1.isEmpty() || !stack2.isEmpty()) {
if (stack1.isEmpty() && !stack2.isEmpty()) {
return false;
} else {
if (stack2.isEmpty() && !stack1.isEmpty()) {
return false;
} else {
if (stack1.pop() == stack2.pop()) {
return true;
} else {
return false;
}
}
}
}
stack1.push(w);
}
}
}
}
if (w == 'B') {
bStart = true;
if(bStart && stack2.isEmpty()) {
stack2.push(w);
}
if(bStart && !stack2.isEmpty()) {
if (!stack1.isEmpty()) {
stack3.push(w);
}
if(!stack3.isEmpty()) {
stack1.push(w);
}
}
}
}
}
return false;
}
This code works correctly for most inputs (returning true for AB and AABBBAABBB, and returning false for BBAA) but in some cases where it should return false (like ABBA and AABBCCD) it returns true. So why is it returning true for cases that are palindromes and cases where there are non A and non B letters. I know I have a statement in there that states if w (the input) is not and A and not a B, return false. This is worked in similar methods I have written, so why not this one? I have also written this to return false if the two returned values don't match (which they shouldn't if the input is a palindrome).
I think you should use .isEqual to compare between two Strings instead of using ==
I am trying to write a method that takes a string of curly brackets and returns true if the brackets match up and false if they don’t.
These are examples of brackets matching:
{ }
{ } { }
{ { } }
{ { { } { { } } } }
These are examples of the brackets not matching:
{
} {
{ { }
{ { } } } { }
I am not able to figure out the proper logic behind this code. I first tried length() mod 2, and only if the result was 0, the method would return true. But obviously, there was a bug because it would return true even for strings such as } {. I added some more code which detects {, and if it doesn't find }, it automatically returns false. But I am still receiving errors.
Here is my code:
public boolean bracketsMatch(String brackets)
{
if(!(brackets.length() % 2 == 0))
{
int i = 0;
int j = 0;
boolean check = false;
while(brackets.charAt(i) == '{')
{
for(int o = i + 1; o < brackets.length(); o++)
{
if(o == '}')
{
check = true;
break;
}
else
{
j++;
}
}
if(check == false)
return false;
i + = j;
}
return true;
}
else
{
return false;
}
}
What would be the correct logic for this problem, and what mistakes am I making? Thanks!
Use counter. Increase it when you find { and decrease when find }. If at some point counter is negative, string is not valid. Return true if after handling all characters counter is 0.
OK
{ }
1 0
{ } { }
1 0 1 0
{ { } }
1 2 1 0
{ { { } { { } } } }
1 2 3 2 3 4 3 2 1 0
Not OK
{
1
} {
-1 <- no point checking farther
{ { }
1 2 1
{ { } } } { }
1 2 1 0 -1 <- no point checking farther
Iterate through the string, if you get an open bracket push it to a stack, if you get a close bracket pop an open bracket from the stack. If the stack is empty when popping, or if when you're finished iterating there are open brackets still on the stack then your brackets are not balanced
If you are checking for the balanced-ness of multiple types ie () [] {} etc then when you pop you need to make sure that the popped opening bracket is of the same type as the closing bracket you have just encountered, if not the brackets are not balanced.
I liked the algorithm described in #Pshemo's answer and an elegant implementation occured to me; you could increment the count on { decrement on } and return false if the result is negative with a simpler for-each loop and a switch. Remembering, to check that the count is 0 at the end with something like
public static boolean bracketsMatch(String brackets) {
int count = 0;
for (char ch : brackets.toCharArray()) {
switch (ch) {
case '{': count++; break;
case '}': if (--count < 0) return false;
}
}
return count == 0;
}
I also created a small unit test for the above using your scenarios
public static void main(String[] args) {
String[] good = { "{ }", "{ } { }", "{ { } }", "{ { { } { { } } } }" };
String[] bad = { "{", "} {", "{ { }", "{ { } } } { }" };
for (String str : good) {
if (!bracketsMatch(str)) {
System.out.printf("error with good: %s%n", str);
}
}
for (String str : bad) {
if (bracketsMatch(str)) {
System.out.printf("error with bad: %s%n", str);
}
}
}
The implementation here passes.
Here is my code... can someone please tell me what is wrong?
void keyPressed() {
if (key == '\n') {
equation = typing;
switch (equation.charAt(2)) {
case "-":
if (equation.charAt(3) == "x") {
math[0] = -1;
};
else {
math[0] = int(equation.charAt(3) * -1);
};
}
}
}
I don't understand what is wrong. All of the braces match up. Is it that you can't use an if else inside a switch???
try replacing
if (equation.charAt(3)=="x") {
math[0] = -1;
};
else {
math[0] = int(equation.charAt(3)*-1);
};
with
if (equation.charAt(3)=='x') { // NOTE character comparision
math[0] = -1;
}
else {
math[0] = int(equation.charAt(3)*-1);
}
I'm trying to make a program that tells me weather the char i put in arguments is uppercase or lowercase or a digit from 0 to 9 or other! I'm having errors in my code:
public class CharsTester {
public static void main(String[] args) {
char input;
if (input.matches("^[a-zA-Z]+$"))
{
if (Character.isLowerCase(input))
{
System.out.println("lower");
}
else
{
System.out.println("upper");
}
}
else if (input.matches("^(0|[1-9][0-9]*)$"))
{
System.out.println("digit");
}
else
{
System.out.println("other");
}
}
}
Change the type of input
String input;// Change char to String
if (input.matches("[a-zA-Z]+")) // Remove ^ and $
// String.matches don't need symbol ^ $
To test char you don't need String#matches,
char input=' ';
if (Character.isLowerCase(input) || Character.isUpperCase(input)) {
if (Character.isLowerCase(input)) {
System.out.println("lower");
} else {
System.out.println("upper");
}
} else if (Character.isDigit(input)) {
System.out.println("digit");
} else {
System.out.println("other");
}
Try:
for (String arg : args) {
if (arg.matches("^[A-Z]+$")) {
System.out.println("uppercase");
} else if (arg.matches("^[a-z]+$")) {
System.out.println("lowercase");
} else if (arg.matches("^[0-9]+$")) {
System.out.println("digits");
} else {
System.out.println("other");
}
}
If your input is in fact one character then you don't need regex but just set of few tests.
char input = 'z';// example character
if (Character.isLowerCase(input)) {
System.out.println("lower");
} else if (Character.isUpperCase(input)) {
System.out.println("upper");
} else if (Character.isDigit(input)) {
System.out.println("digit");
} else {
System.out.println("something is not right :/");
}
Regex groups solution:
Pattern p = Pattern.compile("([a-z])|([A-Z])|([\\d])");
Matcher m = p.matcher("" + x);
m.matches();
if (m.group(1)!=null)
{
System.out.println("lower");
}
else if (m.group(2)!=null)
{
System.out.println("upper");
}
else if (m.group(3)!=null)
{
System.out.println("digit");
} else
{
System.out.println("other");
}
you can convert String to char array, and then individual char with ascii value as below:-
public class CharsTester {
public static void main(String[] args) {
String input="ASD123asd_-";
char temp[]=input.toCharArray();
for (int i=0;i<temp.length;i++)
{
if(temp[i] >47 && temp[i]<58)
{
System.out.println(temp[i]+": is digit");
}
else if(temp[i] >64 && temp[i]<91)
{
System.out.println(temp[i]+": is CAPS char");
}
else if(temp[i] >96 && temp[i]<123)
{
System.out.println(temp[i]+": is small char");
}
else
System.out.println(temp[i]+"is symbol or spetial char");
}
}
}
I am working on a program that solves arithmetic equations. I have encountered a problem that occurs when there are multiple exponential statements in a row the program does not correctly solve them. An example would be: 2^3^2, the correct answer is 512 but the program outputs 64. This is because the program does 2^3 and then 8^2, instead of doing 3^2 and then 2^9. Let me know if you have any ideas on how to modify my current code or have something to add.
import java.text.DecimalFormat;
import java.util.EmptyStackException;
import myUtil.*;
public class PostFixEvaluator extends Asg6
{
public static class SyntaxErrorException extends Exception
{
SyntaxErrorException(String message)
{
super(message);
}
}
private static final String operators = "+-*/^()";
private AStack<Double> operandStack;
private double evaluateOP(char op) throws Exception
{
double rightside = operandStack.pop();
double leftside = operandStack.pop();
double result = 0;
if(op == '+')
{
result = leftside + rightside;
}
else if(op == '-')
{
result = leftside - rightside;
}
else if(op == '*')
{
result = leftside * rightside;
}
else if(op == '/')
{
if(rightside == 0)
{
throw new Exception("Can not divide by 0, the equation is undefined");
}
else
{
result = leftside / rightside;
}
}
else if(op == '^')
{
result = Math.pow(leftside, rightside);
}
return result;
}
private boolean isOperator(char ch)
{
return operators.indexOf(ch) != -1;
}
public double evaluate(String exp) throws Exception
{
operandStack = new AStack<Double>();
String[] tokens = exp.split("\\s+");
try
{
for(String nextToken : tokens)
{
char firstChar = nextToken.charAt(0);
if(Character.isDigit(firstChar))
{
double value = Double.parseDouble(nextToken);
operandStack.push(value);
}
else if (isOperator(firstChar))
{
double result = evaluateOP(firstChar);
operandStack.push(result);
}
else
{
throw new Exception("Invalid character: " + firstChar);
}
}
double answer = operandStack.pop();
if(operandStack.empty())
{
return answer;
}
else
{
throw new Exception("Syntax Error: Stack should be empty");
}
}
catch(EmptyStackException ex)
{
throw new Exception("Syntax Error: The stack is empty");
}
}
}
You're trying to use an LL(1) grammar (which is what a recursive descent parser can parse) to model a right-associative operator (^). A right-associative operator requires left recursion, which doesn't work so easily with LL(1) grammars. You'll want to look at left factoring: http://en.wikipedia.org/wiki/LL_parser#Left_Factoring
I would solve this with operator Priorities as you might want to have them anyway.
For testing i changed the class a bit, so i could test it and its sure not most efficient or readable but you should get
the idea how it works.
import java.text.DecimalFormat;
import java.util.EmptyStackException;
import java.util.*;
public class PostFixEvaluator
{
public static class SyntaxErrorException extends Exception
{
SyntaxErrorException(String message)
{
super(message);
}
}
private static final String operators = "+-*/^()";
private static int[] operatorPriority = {1,1,2,2,3,10,10};
private Stack<Double> operandStack;
private Stack<Character> operatorStack;
private double evaluateOP(char op) throws Exception
{
double rightside = operandStack.pop();
double leftside = operandStack.pop();
double result = 0;
if(op == '+')
{
result = leftside + rightside;
}
else if(op == '-')
{
result = leftside - rightside;
}
else if(op == '*')
{
result = leftside * rightside;
}
else if(op == '/')
{
if(rightside == 0)
{
throw new Exception("Can not divide by 0, the equation is undefined");
}
else
{
result = leftside / rightside;
}
}
else if(op == '^')
{
result = Math.pow(leftside, rightside);
}
return result;
}
private boolean isOperator(char ch)
{
return operators.indexOf(ch) != -1;
}
public double evaluate(String exp) throws Exception
{
operandStack = new Stack<Double>();
operatorStack = new Stack<Character>();
String[] tokens = exp.split("\\s+");
try
{
for(String nextToken : tokens)
{
char firstChar = nextToken.charAt(0);
if(Character.isDigit(firstChar))
{
double value = Double.parseDouble(nextToken);
operandStack.push(value);
}
else if (isOperator(firstChar))
{
// Try to evaluate the operators on the stack
while (!operatorStack.isEmpty())
{
char tmpOperator = operatorStack.pop();
// If Operator has higher Priority than the one before,
// Calculate it first if equal first calculate the second
// operator to get the ^ problem fixed
if (operatorPriority[operators.indexOf(firstChar)] >= operatorPriority[operators.indexOf(tmpOperator)])
{
operatorStack.push(tmpOperator);
// Operand has to be fetched first
break;
}
else
{
double result = evaluateOP(tmpOperator);
operandStack.push(result);
}
}
operatorStack.push(firstChar);
}
else
{
throw new Exception("Invalid character: " + firstChar);
}
}
// Here we need to calculate the operators left on the stack
while (!operatorStack.isEmpty())
{
char tmpOperator = operatorStack.pop();
// Operator Priority has to be descending,
// or the code before is wrong.
double result = evaluateOP(tmpOperator);
operandStack.push(result);
}
double answer = operandStack.pop();
if(operandStack.empty())
{
return answer;
}
else
{
throw new Exception("Syntax Error: Stack should be empty");
}
}
catch(EmptyStackException ex)
{
throw new Exception("Syntax Error: The stack is empty");
}
}
// For testing Only
public static void main(String[] args) throws Exception
{
PostFixEvaluator e = new PostFixEvaluator();
System.out.println(e.evaluate("2 ^ 3 ^ 2"));
}
}