I've tried writing this code from scratch, coding, and running it but it just doesn't seem to work. This was assigned as lab work in class. The requirements are:
Implementing a postfix evaluation with the use of a stack and stack operations (user-defined).
I think the algorithm of my program is right, but it always gives me the wrong answer.
Here is my code.
public class StackApplication {
public static class Stack<T> {
private int top = 0;
private final static int stackMax=100;
// highest index of stk array
private Object[] stk = new Object[stackMax+1];
//Elements must be cast back.
public Stack() { // constructor
}
public boolean isEmpty(){
if (top==0) return true;
else return false;
}
public void push(T el) {
if(top==stackMax)
System.out.println("Stack push overflow error");
else top=top+1;
stk[top]=el;
}
public T pop(){
if(isEmpty()){
System.out.println("Stack push underflow error");
return null;
}
else top=top-1;
return(T)stk[top+1];
}
public T top(){
if(isEmpty()){
//System.out.println("Stack empty");
return null;
}
else return (T)stk[top];
}
}
public static boolean isOperator(char c){
return(c=='+' || c=='-' || c=='/' || c=='*' || c=='^');
}
public static double evaluate(double x, char o, double y) {
double result=0;
switch(o) {
case '+' : result=x+y; break;
case '-' : result=x-y; break;
case '*' : result=x*y; break;
case '/' : result=x/y; break;
case '^' : result=Math.pow(x, y); break;
default : break;
}
return result;
}
public static void main(String[] args) {
Scanner console=new Scanner(System.in);
Stack<Double> s=new Stack<Double>();
System.out.println("Input Postfix form to evaluate:");
String inp=console.nextLine();
char[] chararray=inp.toCharArray();
double b,a;
for(int i=0; i<chararray.length; i++) {
if(!isOperator(chararray[i]))
s.push((double)chararray[i]);
else {
b=s.pop();
a=s.pop();
double c=evaluate(a, chararray[i], b);
s.push(c);
}
}
System.out.println(" " +s.pop());
}
}
Sample Output:
Input Postfix form to evaluate:
23+ (Input)
101.0 (Output)
5.0 (Expected output)
The problem is here: s.push((double)chararray[i]);. You can't convert char to double this way. You are now taking the ascii code of 2 and 3.
50(ascii code of 2) + 51(ascii code of 3) = 101
Do it like this: s.push((double)(chararray[i] - '0'));
Your are doing the addition of the ASCII codes for 2 and 3, not of 2 and 3.
The code for 2 is 50 and for 3 is 51, so your out is 101, which is correct in this case.
When you push, push chararray[i]-'0'. This will solve your problem.
Related
class Solution {
public boolean isoperand(String ch)
{
return(Integer.parseInt(ch)>=0 && Integer.parseInt(ch)<=9) ;
}
public int operate(String ch,int a,int b)
{
switch(ch){
case "*":return a*b;
case "/":return a/b;
case "+":return a+b;
case "-":return a-b;
}
return 0;
}
public int evalRPN(String[] tokens) {
Stack<String> st=new Stack<>();
int l=tokens.length;
for(int i=0;i<l;i++)
{
if(isoperand(tokens[i]))
st.push(tokens[i]);
else{
int b=Integer.parseInt(st.pop());
int a=Integer.parseInt(st.pop());
int result=operate(tokens[i],a,b);
st.push(Integer.toString(result));
}
}
int temp=Integer.parseInt(st.pop());
return temp;
}
}
this is my program to implement evaluation of postfix expression in stack.
Can anyone help me? i get a numberformat exception when the method isoperand is executed. i am fairly new to java.
The issue with your code is that isoperand returns true only if the number lies between 0 and 9, which is not the case. We have numbers that are greater than 9 as well. Hence it results in RuntimeError.
So, it's always better to check if the current token is an operator, if not then it must be an operand.
I've used a set to efficiently check if the current token is an operator or not by adding all operators: +, -, *, / to the set.
Here is an improved version of your code:
class Solution
{
public int operate(String ch, int a, int b)
{
switch (ch)
{
case "*": return a*b;
case "/": return a/b;
case "+": return a+b;
case "-": return a-b;
}
return 0;
}
public int evalRPN(String[] tokens)
{
Set<String> operators = new HashSet<>();
operators.add("*"); operators.add("/");
operators.add("+"); operators.add("-");
Stack<String> stack = new Stack<>();
int len = tokens.length;
for (int i=0; i<len; i++)
{
if (operators.contains(tokens[i]))
{
int b = Integer.parseInt(stack.pop());
int a = Integer.parseInt(stack.pop());
int result = operate(tokens[i], a, b);
stack.push(Integer.toString(result));
}
else
stack.push(tokens[i]);
}
return Integer.parseInt(stack.pop());
}
}
Runtime: 4 ms, faster than 88.95% of Java submissions
I'm trying to use a java Stack to push String values:names into it, derived from input from a Scanner method. I'd then want to pop the names from the stack, and after show the logical and physical elements of the stack. I believe I should be using an Array Stack but not entirely sure as I don't have much quidance or experience with Stacks.
Currently I am getting the following error when compiling the Stack.java file.
Stack.java:24: cannot find symbol
symbol : method push(java.lang.String)
location: class java.lang.String[]
stack.push(s);
I've been researching this and trying different code for days, but as I am very new to this, and I have run out of ways to manipulate the code to make it work.
I would highly appreciate some advice...tnx!
Here is my Stack Class code:
import java.lang.*;
import java.util.*;
public class Stack { //Create Class
private String stack[] ;
private int top;
private static final int SIZE = 5;
String name;
Scanner scan = new Scanner(System.in);
public Stack(int SIZE){
stack = new String [SIZE];
top = 0;
}
public void push(String s) { //Method to Insert
if (isStackFull())
System.out.println ("Stack is Full "); //If Stack full Print Full
else {
while (scan.hasNextLine()){
s = scan.nextLine();
stack.push(s);
}
stack[top] = s;
top++;
}
}
public String pop() { //Method to Delete
if (isStackEmpty())
System.out.println ("Stack is Empty "); //If Stack empty print Empty
else{
String value = stack[top];
top--;
return value;
}
return stack[top];
}
public String toString( ){ //Method print Logical Stack
if (isStackEmpty( ))
System.out.println ("Stack is Empty "); //If Stack empty print Empty
else
System.out.println("\nThe Stack");
String result = "";
for (int j=0; j < top; j++)
result = result + stack[j].toString() + "\n";
return result;
}
public boolean isStackEmpty() { //Method boolean type to check empty Stack
return (top == 0);
}
public boolean isStackFull() { //Method boolean type to check full Stack
return (top == (SIZE-1));
}
}
For the StackTest Code, generally I call the methods in Stack. Eg.
public class StackTest { //Create class
public static void main(String[] args){ //Main Method
Stack n = new Stack(); //Declare variables
Scanner in = new Scanner(System.in);
String response;
char x;
and
while(x != 'q' && x != 'Q'){ //While loop initiates if no q or Q char input
switch(x){ //Start of swtich for insert, delete, print physical, logical or default quite
case 'i':
n.push();
System.out.println ("Inserted item from Stack");
break;
case 'd':
n.pop();
System.out.println ("Deleted item from Stack");
break;
case 'p':
n.toString();
System.out.println ("Printed Physical Stack ");
break;
Your push(String s) is method is calling push() on String which is incorrect, moreover the logic for push(String s) is complicated, rather it is simple as shown below in the code with comments:
public void push(String s) {
if (isStackFull())
System.out.println ("Stack is Full "); //If Stack full Print Full
else {
stack[top] = s; //just add the string to the top of the stack
top++; //increment top
}
}
In the push method itself you are trying to call stack.push hence it is throwing error. replace the stack.push to stack[top_index]= the string.
http://codingbat.com/prob/p126880
Given two strings, return true if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be "case sensitive"). Note: str.toLowerCase() returns the lowercase version of a string.
I cannot get when it is true, it always gives false.
public boolean endOther(String a, String b)
{
//variables
a.toLowerCase();
b.toLowerCase();
String f1="";
String f2="";
int d=0;
int sum=0;
//Program code;
if(a.length()-b.length()>0)
{
(f1).equals(a);
(f2).equals(b);
d=a.length();
}
else if(a.length()-b.length()<0)
{
(f1).equals(b);
(f2).equals(a); //gett**ing bigger and lower String**
d=b.length();
}
else if((a).equals(b))
sum++;
// I think problem is because it is not enter the for.
for(int i=0; i>d; i++)
{
if((f1.substring(i,i+f2.length())).equals(f2))
sum++;
}
if(sum>0)
return true;
else
return false;
}
This is a working example of what you are trying to achieve to test in your Java IDE like Netbeans or Eclipse whatever. This is really simple, the String object has an endsWith method so why try to invent something yourself.
If you have any troubles reading this code hit me up, should be quite straight forward. You will just have to convert your string to lowercase, that's for you to add.
public class StringEnds {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.printf("String a: ");
String a = scanner.next();
System.out.printf("String b: ");
String b = scanner.next();
// Compare a and b
if (endsWith(a, b)) {
System.out.printf("Succes\n");
} else {
System.out.printf("Fail\n");
}
}
public static boolean endsWith(String firstString, String secondString) {
return firstString.endsWith(secondString) || secondString.endsWith(firstString);
}
}
Here's your codebat solution (it is quite short):
public boolean endOther(String a, String b) {
return a.toLowerCase().endsWith(b.toLowerCase()) || b.toLowerCase().endsWith(a.toLowerCase());
}
This is my answer. I tried both ways, hope it helps.
public boolean endOther(String a, String b) {
int small = Math.min(a.length(), b.length());
if (a.length()==b.length() && a.equalsIgnoreCase(b)) {
return true;
}
if (small==a.length()) {
if (b.substring(b.length()-small).equalsIgnoreCase(a)) {
return true;
}
// from here is the toLowerCase() method.
a = a.toLowerCase();
b = b.toLowerCase();
} else if (small==b.length()) {
if (a.endsWith(b)) {
return true;
}
}
return false;
}
I'm a computer science student that just started my sophomore programming class and I'm having some real issues with a project that deals with Stacks and collections.
Basically, this is a project that relies on the ArrayStack Class(ArrayStack, to be specific) to convert mathematical expressions between postfix and infix forms.
Basically, ArrayStack is used to take in an expression like 45 * (26 - 5) / 54, turn it into a collection, then rewrite in a postfix form like 45 26 5 - * 54 /
The problem is, first of all, whenever I try to substitute with Character in the main method(since the stack needs to store both operators and operands, maybe there's a better data type I'm missing here), I get some strange syntax error, usually involving the program thinking that ArrayStack.System is somehow a statement(System.out.println is right below an ArrayStack statement, which suggests there's some kind of syntax problem)
Here's the code I have so far:
public class ArrayStack<T> implements StackADT<T>
{
private static final int DEFAULT_CAPACITY = 100;
private int top;
private T[] stack;
public ArrayStack() {
top = -1;
stack = (T[]) (new Object[DEFAULT_CAPACITY]);
}
public void push(T element) {
stack[top+1] = element;
top++;
}
public T pop() {
T element = stack[top];
stack[top] = null;
top--;
return element;
}
public T peek() {
return stack[top];
}
public boolean isEmpty() {
if(stack[0]==null)
return true;
else{
return false;
}
}
public int size() {
int length = 0;
for(int count=0;count<stack.length;count++) {
if(stack[count]!=null) {
length++;
}
else if(stack[count]==null) {
break;
}
}
return length;
}
public String toString() {
String array = "";
for(int count=0;count<stack.length;count++) {
array = array+stack[count]+" ";
}
return array;
}
}
And for the main method:
public class StackTester {
public static void main(String[] args) {
boolean quit = false;
int input;
String expression;
do {
System.out.println("1. Convert infix to postfix");
System.out.println("2. Convert postfix to infix");
System.out.println("3. Exit.");
java.util.Scanner keyboard = new java.util.Scanner(System.in);
input = keyboard.nextInt();
switch(input) {
case 1:
//ArrayStack stack = new ArrayStack();
//System.out.println("Enter an infix expression: ");
expression = keyboard.next();
for(int count=0;count<expression.length();count++) {
Character a = expression.charAt(count);
stack.push(a);
}
for(int count=stack.size()-1;count>=0;count--) {
if(stack.peek()=='+') {
}
}
}
break;
}
while(!quit);
}
}
The error usually occurs at the lines marked with //, every time I try to insert something like or otherwise, the program gives some weird syntax error like its trying to read it together with the line below it. Any ideas what's going on here?
I need to make a simple calculator. I am having trouble with entering any amount of operators and operands, then outputting the answer when the equals button has been entered.
So far, if I just press one number and a digit it exits but does not give me an answer. If I do more than one operator and operand then = it does not exit the loop.
For example it should be like:
5
+
5
+
5
=
15
Here is my code, Calculator:
public interface Calculator {
public void setOperator(char operator); // eg +-*/=
public void setOperand (double operand); // eg 123.456
public double getResult();
}
SimpleCalculator:
import java.io.*;
public class SimpleCalculator implements Calculator {
char operator;
double operand;
double result;
double answer;
public void setOperator(char operator){
this.operator = operator;
}
public char getOperator(){
return operator;
}
public void setOperand(double operand){
this.operand = operand;
}
public double getOperand(){
return operand;
}
public double getResult(){
if (getOperator() == '+'){
result = (getOperand() + getOperand());
}
if (getOperator() == '-'){
result = (getOperand() - getOperand());
}
if (getOperator() == '*'){
result = (getOperand() * getOperand());
}
if (getOperator() == '/')
{
result = (getOperand() / getOperand());
}
if (getOperator() == '=')
result = answer;
}
return result;
}
public boolean getanswer(String value)
{
boolean isnum = false;
try {
setOperand(Double.parseDouble(value));
operand = (Double.parseDouble(value));
getResult();
isnum = true;
}
catch(Exception e)
{
try {
setOperator(value.charAt(0));
operator = (value.charAt(0));
isnum = false;
}
catch(Exception e2)
{
{
System.out.println("Enter a number");
}
}
return isnum;
}
}
SimpleTest:
import java.io.*;
public class SimpleTest{
static String value;
static double operand;
static char operator;
static boolean isnum;
public static void main(String[] argv){
SimpleCalculator calculator = new SimpleCalculator();
value = UserInput.readString();
while (!(value.equals("=")))
{
isnum = calculator.getanswer(value);
if (!(isnum == true))
{
break;
}
}
System.out.println(calculator.getResult());
}
}
Based on the title of your question I found that you might see an issue with your main-loop:
value = UserInput.readString();
while (!(value.equals("="))) {
isnum = calculator.getanswer(value);
if (!(isnum == true)) {
break;
}
}
Since you read the user input outside the loop it will never change and this will either run only once (if isnum is false) or infinitely (if isnum is true) -- getanswer does not has a memory with respect to its result. Thus if you input a number it will loop forever but not doing anything useful.
Please note: this is just a first guess. I didn't check the rest of your program.
You didn't really say what your problem is, but I found one for you:
You are using
result = (getOperand() + getOperand();
(and similar) to calculate your results. But getOperand() always returns the same result (since you can't execute setOperand() between these calls), so you are always adding, subtracting, multiplying and dividing the same number.