!("(").equals(stack.peek()) not working properly - java

Recently I've been working on creating a calculator by implementing a stack in java. I've run into some trouble with stack.peek().equals("(") in my code and I have tried a few different methods to solve this issue but nothing seems to work.
Here is my code below:
import java.util.Scanner;
import java.util.Stack;
public class URCalculator {
public static Scanner scan = new Scanner(System.in);
public static Stack<String> uRStack = new Stack<String>();
public static Stack<String> uROPStack = new Stack<String>();
public static void main(String[] args) {
prompt();
String val = scan.next();
pusher(splitInput(val));
while(!uRStack.empty()) {
System.out.println(uRStack.pop());
}
}
public static String[] splitInput(String val) {
return val.split("(?!^)");
}
public static void pusher(String[] s) {
int counter = 0; // counter determines if there is a numeric value
in the index prior, if so then we concatenate and add back to the stack.
for(int i=0; i<s.length; i++) { // loops through split input array
if(isNumeric(s[i]) && counter != 0) { // checks if number and if
previous number
pushNumeric(uRStack.pop() + s[i]);
counter++;
}
else if (isNumeric(s[i])) { // checks if just a number
pushNumeric(s[i]);
counter++;
}
else if(isOperator(s[i])) { // if not number then reset counter for latter values
addOperator(s[i]);
counter=0;
}
}
uRStack.push(uROPStack.pop());
}
public static void addOperator(String s) { // uses cases to determine logic for operator stack
switch(s) {
case "+":
if(!uROPStack.empty()){
while(!"(".equals(uROPStack.peek()) && !uROPStack.empty()) { // while operators not of lower precedence then push pop
uRStack.push(uROPStack.pop());
}
}
uROPStack.push(s);
break;
case "-":
if(!uROPStack.empty()){
while(!"(".equals(uROPStack.peek()) && !uROPStack.empty()) { // while operators not of lower precedence then push pop
uRStack.push(uROPStack.pop());
}
}
uROPStack.push(s);
break;
case "*":
if(!uROPStack.empty()) {
while("*".equals(uROPStack.peek()) || !"/".equals(uROPStack.peek())) { // while operators of equal or greater precedence then push pop
uRStack.push(uROPStack.pop());
}
}
uROPStack.push(s);
break;
case "/":
if(!uROPStack.empty()) {
while("*".equals(uROPStack.peek()) || !"/".equals(uROPStack.peek())) { // while operators of equal or greater precedenc then push pop
uRStack.push(uROPStack.pop());
}
}
uROPStack.push(s);
break;
case "(":
uROPStack.push(s);
break;
case ")":
if(!uROPStack.empty()){
while(!"(".equals(uROPStack.peek())) {
uRStack.push(uROPStack.pop());
}
}
break;
}
}
I have added my main and pusher methods for context, but the real issue lies in the addOperation method, specifically the first boolean within the while loop. The error I get is posted below:
Hello and welcome to the URCalculator. Please type an operation
1-2-3-4-5
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Unknown Source)
at URCalculator.addOperator(URCalculator.java:129)
at URCalculator.pusher(URCalculator.java:107)
at URCalculator.main(URCalculator.java:14)
I understand my code is not the most elegant of the sorts, nor is it finished, but I can't seem to understand why I'm receiving the error I'm getting. One thing I have checked is that when I remove the !"(".equals(uROPStack.peek())
from the expression entirely, things seem to run smoothly. The problem is that I still need to handle the paranthetical case in my stack so I don't know what to do.

This condition is broken:
!"(".equals(uROPStack.peek()) && !uROPStack.empty()
If uROPStack is empty, then uROPStack.peek() will throw EmptyStackException.
If you flip the conditions, it will work as intended:
!uROPStack.empty() && !"(".equals(uROPStack.peek())
Here, thanks to the short-circuiting behavior of the && operator,
if the first condition is false (= the stack is empty),
then the second condition (the .peek()) will not be executed,
and you get the desired behavior.
You didn't ask about it, but another problem is waiting to explode here too:
if(!uROPStack.empty()) {
while("*".equals(uROPStack.peek()) || !"/".equals(uROPStack.peek())) {
uRStack.push(uROPStack.pop());
}
}
That is, since you uROPStack.pop() in the body of the while loop,
the uROPStack.peek() in the loop condition may lead to EmptyStackException. You need to make sure the stack is not empty in the loop condition:
while(!uROPStack.peek().isEmpty() && ("*".equals(uROPStack.peek()) || !"/".equals(uROPStack.peek()))) {

Related

multiple if statements and a loop

I have a logical problem. I will provide pseudo code since the real code isn't all that readable. I want to only enter one of the instructions, and if none of the instructions are reachable I want the function to break out from the loop.
I'm pretty new to programming so any help is appreciated.
edit: In every iteration I want to only reach one of the conditions. Since there is a loop going on for a longer time I want to be able to reach the same / other instructions for every iteration
while(true){
if(condition){ // Instruction 1
do stuff
}else{
do stuff
}
if(condition){ // Instruction 2
do stuff
}else{
do stuff
}
if(condition){ // Instruction 3
do stuff
}else{
do stuff
}
if(condition){ // Instruction 4
do stuff
}else{
do stuff
}
if(none condition){
break;
}
}
I don't think anyone's got this spot on so far so I'll throw in my understanding of what you're asking.
while(true) // keep looping
{
boolean instructionExecuted = false; // we haven't done an instruction this iteration
// Instruction 1
if(condition) {
instructionExecuted = true;
//do stuff
} else {
//do stuff
}
// Instruction 2
if(condition && !instructionExecuted) { // If we've not done an instruction,
// and we can do instruction #2
instructionExecuted = true;
//do stuff
} else if (!instructionExecuted) { // only do this if we haven't already
// done an instruction
//do stuff
}
// Instruction 3
if(condition && !instructionExecuted) { // If we've not done an instruction,
instructionExecuted = true; // and we can do instruction #3
//do stuff
} else if (!instructionExecuted) { // only do this if we haven't already
// done an instruction
//do stuff
}
//etc.
if(none condition)
{
break;
}
}
Adding a bool trigger might be what you are looking for. if you enter any if statements turn the trigger to true.
You're making this harder than it has to be. All you need to do is have an if statement with multiple else if statements after it.
Example:
if (condition) {
doStuff();
} else if (condition) {
doStuff();
} else if (condition) {
...
} else {
break;
}
well, there are multiple ways to accomplish what you want:
Introduce a top-level boolean flag doNotBreak and set true in if/else blocks execution of which means the loop should not break.
Check should it break or not by combining conditions using in the loop: if(condition1 && !condition2 && ..) break;
Instead of the last condition, break with condition and inside if/else block where you don't want to break, use continue.
boolean reachable = false;
while(true){
if(condition){ // Instruction 1
do stuff
reachable = true
}else{
do stuff
}
if(condition){ // Instruction 2
do stuff
reachable = true
}else{
do stuff
}
if(condition){ // Instruction 3
do stuff
reachable = true
}else{
do stuff
}
if(condition){ // Instruction 4
do stuff
reachable = true
}else{
do stuff
}
if(!reachable){
break;
}
}
Alternatively you can check if it is possible to use switch Statements instead of if-else. Example
public static void main(String argv[]) {
String [] conditions = {"condition_1","condition_2","condition_3","condition_4","xyz"};
printConditionType(conditions);
}
public static void printConditionType(String [] conditions){
int i = 0;
while (i<conditions.length){
switch (conditions[i]) {
case "condition_1":
System.out.println("#1");
break;
case "condition_2":
System.out.println("#2");
break;
case "condition_3":
System.out.println("#3");
break;
case "condition_4":
System.out.println("#4");
break;
default:
System.out.println("Invalid condition:" + conditions[i]);
}
i++;
}
}

Java BinarySearch program

I am learning Java programming and made a program which uses Binary Search to find a symbol in an array of char. However, I have a problem when I try to search for the symbol which is not in an array, my program becomes an endless cycle. I have no idea how to make an error sign if there is no such symbol in an array. Here is the code of my program
import java.lang.reflect.Array;
import java.util.Arrays;
public class Main {
public static void main(String[] args){
char[]arr = {'a','d','f','l','o','z'};
find(arr,'m');
}
public static void find(char[]arr,char ch){
int last = arr.length-1;
int mid=last;
while (arr[mid] != ch){
if (arr[mid]<ch){
mid = (last+mid)/2;
}
else{
last=mid;
mid=last/2;
}
}
System.out.print(mid);
}
}
Thank you in advance.
You have no case to break out of the while loop and the changed values assigned to the variables during the 2 if cases are incorrect. Plus, you should also check for when the element is found in the if-else ladder and use a variable (found) to indicate whether the element is found. Moreover, it'll be better if you use 3 variables for the lower bound (first), mid and upper bound (last). The code below is a revision of the find() method.
public static void find(char[]arr,char ch){
int first=0,mid=0,last=arr.length-1,found=0;
while (first<=last){
mid=(last+first)/2;
if(arr[mid]==ch){
System.out.print(ch+" found at index "+mid);
found=1;
break;
}
else if(arr[mid]<ch){
first=mid+1;
}
else if(arr[mid]>ch){
last=mid-1;
}
}
if(found==0)
System.out.print(ch+" was not found ");
}
This works fine and maybe you should use this method.
You have to make some changes in your find() method.First check that the value of mid should never exceed the value of last,so you have to change your while loop condition accordingly. Secondly you have to give a terminating condition if(arr[mid]==ch) to come out of the loop.
This can also be done by using two variables lo & hi ,easy to understand & implement.See the implementation here Binary Search.
Below is the solution using only only last & mid variables,as per your code requirement above:
public static void find(char[]arr,char ch){
int last = arr.length-1;
int mid=last/2;
while (mid<=last){
if(arr[mid] == ch) //if found, Print and exit the loop
{
System.out.println("found at:"+mid);
return;
}
if (arr[mid]<ch){
mid=((last+mid)/2)+1;
}
else{
last=mid-1;
mid=last/2;
}
}
System.out.println("Not found!!");
}

Simple Binary Search Program....Please tell me what is wrong in this specific code

Im a beginner.
Here is a binary search code.Its showing array out of bounds error for main method.
please look into the program and kindly tell me my mistake.ill be grateful for ur service.
i have to write all this crap cause i cant post it as its asking for more details.
public class BinaryS
{
int n;
public BinaryS(int z)
{
n=z;
}
static int pos;
static boolean flag=false;
public void disp()
{
int arr[]={0,1,2,3,4};
int len=arr.length;
int first=0;
int last=len;
int mid=(int)(first+last/2);
//boolean flag=false;
while(mid>=0 && mid<=len)
{
if(n<arr[mid])
{
last=mid;
}
if(n>arr[mid])
{
first=mid;
}
if(n==arr[mid])
{
flag=true;
pos=mid+1;
}
}
if(flag==true){
System.out.println("the no."+n+"is found at"+pos);
}
else{
System.out.println("the no."+n+"is not found ");
}
}
public static void main(String args[])
{
BinaryS obj=new BinaryS(2);
obj.disp();
}
}
Currently your code does compile, and runs forever - because of this loop:
while(mid>=0 && mid<=len)
{
// Code which doesn't modify mid or len
}
Assuming it gets into that loop at all (which it does), the condition is never going to become false - so unless you return or break from within the loop (you don't) or an exception is thrown (it isn't) you're just going to keep going round the loop.
This is where you should:
Use a debugger to observe what's happening
Think about what the condition should actually be and how you want it to become false
Adjust your code to either change the condition, or change the loop body so that it modifies mid or len

Switch with if, else if, else, and loops inside case

For the purpose of my question I've only included case 1, but the other cases are the same. Let's say value is currently 1, we go to case 1 and our for loop goes through the array to see if each element matches with the whatever_value variable. In this case if it does, we declare the value variable to be equal to 2, and we break out of the loop. The problem is that when i highlight the other break(in eclipse), it says that the breaks are attached to the for statement as well, but i only wanted the for statement to be attached to the if statement, not the else if statements as well. I thought because there are no brackets for the for statement that it would only loop for the if statement but eclipse says otherwise(else if also loops from 0 to the length of the array).
switch (value) {
case 1:
for (int i = 0; i < something_in_the_array.length; i++)
if (whatever_value == (something_in_the_array[i])) {
value = 2;
break;
} else if (whatever_value == 2) {
value = 3;
break;
} else if (whatever_value == 3) {
value = 4;
break;
}
break;
case 2:
// code continues....
Your problem..... I think is that your for loop is encompassing all of the if, else if stuff - which acts like one statement, like hoang nguyen pointed out.
Change to this. Note the brackets that denote the code block on which the for loop operates and the change of the first else if to if.
switch(value){
case 1:
for(int i=0; i<something_in_the_array.length;i++) {
if(whatever_value==(something_in_the_array[i])) {
value=2;
break;
}
}
if(whatever_value==2) {
value=3;
break;
}
else if(whatever_value==3) {
value=4;
break;
}
break;
case 2:
code continues....
In this case, I'd recommend using break labels.
http://www.java-examples.com/break-statement
This way you can specifically call it outside of the for loop.
Seems like kind of a homely way of doing things, but if you must...
you could restructure it as such to fit your needs:
boolean found = false;
case 1:
for (Element arrayItem : array) {
if (arrayItem == whateverValue) {
found = true;
} // else if ...
}
if (found) {
break;
}
case 2:
If you need the for statement to contain only the if, you need to remove its else, like this:
for(int i=0; i<something_in_the_array.length;i++)
if(whatever_value==(something_in_the_array[i]))
{
value=2;
break;
}
/*this "else" must go*/
if(whatever_value==2)
{
value=3;
break;
}
else if(whatever_value==3)
{
value=4;
break;
}
but i only wanted the for statement to be attached to the if statement, not the else if statements as well.
Well get rid of the else then. If the else if is not supposed to be part of the for then write it as:
for(int i=0; i<something_in_the_array.length;i++)
if(whatever_value==(something_in_the_array[i]))
{
value=2;
break;
}
if(whatever_value==2)
{
value=3;
break; // redundant now
}
else if(whatever_value==3)
{
value=4;
break; // redundant now
}
Having said that:
it is not at all clear what you are really trying to do here,
not having the else part in the loop doesn't seem to make a lot of sense here,
a lot of people (myself included) think it is to always use braces ... so that people don't get tripped up by incorrect indentation when reading your code. (And in this case, it might help us figure out what you are really trying to do here ...)
Finally, braces are less obtrusive if you put the opening brace on the end of the previous line; e.g.
if (something) {
doSomething();
}
rather than:
if (something)
{
doSomething();
}

Difference between Return and Break statements

How does a return statement differ from break statement?.
If I have to exit an if condition, which one should I prefer, return or break?
break is used to exit (escape) the for-loop, while-loop, switch-statement that you are currently executing.
return will exit the entire method you are currently executing (and possibly return a value to the caller, optional).
So to answer your question (as others have noted in comments and answers) you cannot use either break nor return to escape an if-else-statement per se. They are used to escape other scopes.
Consider the following example. The value of x inside the while-loop will determine if the code below the loop will be executed or not:
void f()
{
int x = -1;
while(true)
{
if(x == 0)
break; // escape while() and jump to execute code after the the loop
else if(x == 1)
return; // will end the function f() immediately,
// no further code inside this method will be executed.
do stuff and eventually set variable x to either 0 or 1
...
}
code that will be executed on break (but not with return).
....
}
break is used when you want to exit from the loop, while return is used to go back to the step where it was called or to stop further execution.
No offence, but none of the other answers (so far) has it quite right.
break is used to immediately terminate a for loop, a while loop or a switch statement. You can not break from an if block.
return is used the terminate a method (and possibly return a value).
A return within any loop or block will of course also immediately terminate that loop/block.
You won't be able to exit only from an if condition using either return or break.
return is used when you need to return from a method after its execution is finished when you don't want to execute the rest of the method code. So if you use return, then you will not only return from your if condition, but also from the whole method.
Consider the following method:
public void myMethod()
{
int i = 10;
if(i==10)
return;
System.out.println("This will never be printed");
}
Here, using return causes to stop the execution of the whole method after line 3 and execution goes back to its caller.
break is used to break out from a loop or a switch statement. Consider this example -
int i;
for(int j=0; j<10; j++)
{
for(i=0; i<10; i++)
{
if(i==0)
break; // This break will cause the loop (innermost) to stop just after one iteration;
}
if(j==0)
break; // and then this break will cause the outermost loop to stop.
}
switch(i)
{
case 0: break; // This break will cause execution to skip executing the second case statement
case 1: System.out.println("This will also never be printed");
}
This type of break statement is known as unlabeled break statement. There is another form of break, which is called labeled break. Consider this example -
int[][] arrayOfInts = { { 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i;
int j = 0;
boolean foundIt = false;
search:
for (i = 0; i < arrayOfInts.length; i++)
{
for (j = 0; j < arrayOfInts[i].length; j++)
{
if (arrayOfInts[i][j] == searchfor)
{
foundIt = true;
break search;
}
}
}
This example uses nested for loops to search for a value in a two-dimensional array. When the value is found, a labeled break terminates the outer for loop (labeled "search").
You can learn more abour break and return statements from JavaDoc.
Break statement will break the whole loop and execute the code after loop and Return will not execute the code after that return statement and execute the loop with next increment.
Break
for(int i=0;i<5;i++){
print(i)
if(i==2)
{
break;
}
}
output: 0 1
return
for(int i=0;i<5;i++)
{
print(i)
if(i==2)
{
return;
}
}
output: 0 1 3 4
break:- These transfer statement bypass the correct flow of execution to outside
of the current loop by skipping on the remaining iteration
class test
{
public static void main(String []args)
{
for(int i=0;i<10;i++)
{
if(i==5)
break;
}
System.out.println(i);
}
}
output will be
0
1
2
3
4
Continue :-These transfer Statement will bypass the flow of execution to starting point of the loop inorder to continue with next iteration by skipping all the remaining instructions .
class test
{
public static void main(String []args)
{
for(int i=0;i<10;i++)
{
if(i==5)
continue;
}
System.out.println(i);
}
}
output will be:
0
1
2
3
4
6
7
8
9
return :-
At any time in a method the return statement can be
used to cause execution to branch back to the caller of the method.
Thus, the return statement immediately terminates the method in which
it is executed. The following example illustrates this point. Here,
return causes execution to return to the Java run-time system,
since it is the run-time system that calls main( ).
class test
{
public static void main(String []args)
{
for(int i=0;i<10;i++)
{
if(i==5)
return;
}
System.out.println(i)
}
}
output will be :
0
1
2
3
4
You use break to break out of a loop or a switch statement.
You use return in a function to return a value. Return statement ends the function and returns control to where the function was called.
break breaks the current loop and continues, while return it will break the current method and continues from where you called that method
Break will only stop the loop while return inside a loop will stop the loop and return from the function.
Return will exit from the method, as others have already pointed out. If you need to skip just over some part of the method, you can use break, even without a loop:
label: if (some condition) {
// some stuff...
if (some other condition) break label;
// more stuff...
}
Note, that this is usually not good style, though useful sometimes.
How does a return statement differ from break statement?.
Return statement exits current method execution and returns value to calling method.
Break is used to exit from any loop.
If I have to exit an if condition, which one should I prefer, return or break?
To exit from method execution use return.
to exit from any loop you can use either break or return based on your requirement.
break just breaks the loop & return gets control back to the caller method.
In this code i is iterated till 3 then the loop ends;
int function (void)
{
for (int i=0; i<5; i++)
{
if (i == 3)
{
break;
}
}
}
In this code i is iterated till 3 but with an output;
int function (void)
{
for (int i=0; i<5; i++)
{
if (i == 3)
{
return i;
}
}
}
If you want to exit from a simple if else statement but still stays within a particular context (not by returning to the calling context), you can just set the block condition to false:
if(condition){
//do stuff
if(something happens)
condition = false;
}
This will guarantee that there is no further execution, the way I think you want it..You can only use break in a loop or switch case

Categories

Resources