Hello I am practicing some stacks on Java and I am trying to do a problem concerning stacks. I was trying to write a method that takes a postfix notation and converts it into infix. This is what i have so far:
`
public void convertion() {
Stack<Integer> stack; // For evaluating the expression.
stack = new Stack<Integer>(); // Make a new, empty stack.
Scanner scan = new Scanner(postfix);
int t1, t2 = 0; //Operands
boolean check = false;
while (scan.hasNext() && !check) {
if (scan.hasNextInt()) {
int operand = scan.nextInt();
stack.push(operand);
} else {
char operator = scan.next().charAt(0);
try {
while(stack.)
} catch (EmptyStackException e) {
answer = "Malformed postfix expression";
check = true;
}
}
}
scan.close();
try {
answer = "" + stack.pop();
} catch (EmptyStackException e) {
answer = "Malformed postfix expression";
}
}
`
The part im having trouble with is on what i should put on the try part. Basically Im pushing all the numbers i find into the stack, but once i find an operator, how do i merge the two operands and the operator.
Thanks.
You want to pop the top two stack elements, perform the appropriate operation on them and then push back the result:
try {
int o1 = stack.pop().intValue();
int o2 = stack.pop().intValue();
switch (operator) {
case '+': stack.push(new Integer(o1 + o2));
break;
case '-': stack.push(new Integer(o1 - o2));
break;
...
}
}
catch (EmptyStackException e) {
...
Related
The first for loop prints the proper coeffcient and exponent values as
provided by the value string, but the second for loop which class the
addLink method does not print the proper values? I cannot see what the
problem is. Why does the output from the first for loop not match the output from the second?
The code has been edited. I have moved the addLink method into the first for loop and my output is shown below. it is still not what I am intending.
public class Polyvalues {
Term head;
public Polyvalues() {
String value = "5 6 8 9 1 9";
String sub[] = value.split(" ");
double coeff = 0;
int exp = 0;
for (int i = 0; i < sub.length; i++)
{
if (sub[i].isEmpty()) {
System.out.println("No input");
}
if (i % 2 == 0) {
try {
coeff = Double.parseDouble(sub[i]);
System.out.println("Coeff is " + coeff);
} catch (NumberFormatException e) {
System.out.println("Fix This");
}
} else {
try {
exp = Integer.parseInt(sub[i]);
System.out.println("The exp is " + exp);
} catch (NumberFormatException e) {
System.out.println("Fix This");
}
}
this.addLink(coeff, exp);//moved from commented out for-loop
}
System.out.println("*******************************************");
/*for (int i = 0; i < sub.length; i++)
{
this.addLink(coeff, exp);
}*/
}//end constructor
public void addLink(double a, int b)
{
if(head == null)
{
head = new Term(a,b);
return;
}
Term currNode = head;
while(currNode.next != null)
{
currNode = currNode.next;
}
currNode.next = new Term(a,b);
//addLink(a,b);
}
static class Term{
double coeff;
int exp;
Term next;
Term(double c, int e){
this.coeff = c;
this.exp = e;
this.next = null;
System.out.println("The Coeff "+ this.coeff);
System.out.println("The Exp "+ this.exp);
}
}
public static void main(String[] args)
{
Polyvalues p1 = new Polyvalues();
}
} //end of class
Now, I get this when I move the addLink method into the first for-loop. Why am I getting these duplicate outputs when I print?
When this is what I want:
Is it my nodes?
Because in the second loop you are passing the same value of coeff and exp every time.
At the end of your first loop value of coeff is 1.0 and exp is 9
and you are passing that same value every time, in the second loop, to method addLink.
To solve it either make an array to store every value or just call addLink in the first loop.
You really need to learn how to debug your code. Every programmer needs to know how to debug code. Have you read this Web page? How to debug small programs
In any case, if you are using an IDE (like Eclipse or IntelliJ) then it should have a debugger and you should learn to use it.
You are close with your code. You just need to move the call to method addLink. (See the below code.) If you step through the code using a debugger, you will understand why. Basically you need to call addLink after you have obtained a value for both coeff and exp. In your code you are calling addLink twice – once when you only have the coeff value and the second time when you have both coeff and exp.
In the below code, I have indicated the change with the comment Moved from after this 'else' block. I also left the original line but commented it out.
Also note that I added [overridden] toString methods just to make it easier to see the results of executing the code.
public class Polyvalues {
Term head;
public Polyvalues() {
String value = "5 6 8 9 1 9";
String sub[] = value.split(" ");
double coeff = 0;
int exp = 0;
for (int i = 0; i < sub.length; i++) {
if (sub[i].isEmpty()) {
System.out.println("No input");
}
if (i % 2 == 0) {
try {
coeff = Double.parseDouble(sub[i]);
System.out.println("Coeff is " + coeff);
}
catch (NumberFormatException e) {
System.out.println("Fix This");
}
}
else {
try {
exp = Integer.parseInt(sub[i]);
System.out.println("The exp is " + exp);
this.addLink(coeff, exp); // Moved from after this 'else' block.
}
catch (NumberFormatException e) {
System.out.println("Fix This");
}
}
//this.addLink(coeff, exp);//moved from commented out for-loop
}
System.out.println("*******************************************");
}// end constructor
public void addLink(double a, int b) {
if (head == null) {
head = new Term(a, b);
return;
}
Term currNode = head;
while (currNode.next != null) {
currNode = currNode.next;
}
currNode.next = new Term(a, b);
// addLink(a,b);
}
public String toString() {
StringBuilder sb = new StringBuilder();
Term curr = head;
while (curr != null) {
sb.append(curr);
curr = curr.next;
}
return sb.toString();
}
static class Term {
double coeff;
int exp;
Term next;
Term(double c, int e) {
this.coeff = c;
this.exp = e;
this.next = null;
System.out.println("The Coeff " + this.coeff);
System.out.println("The Exp " + this.exp);
}
public String toString() {
return String.format("[C=%.2f,E=%d]-> ", coeff, exp);
}
}
public static void main(String[] args) {
Polyvalues p1 = new Polyvalues();
System.out.println(p1);
}
} // end of class
Running the above code prints the following:
Coeff is 5.0
The exp is 6
The Coeff 5.0
The Exp 6
Coeff is 8.0
The exp is 9
The Coeff 8.0
The Exp 9
Coeff is 1.0
The exp is 9
The Coeff 1.0
The Exp 9
The Coeff 1.0
The Exp 9
*******************************************
[C=5.00,E=6]-> [C=8.00,E=9]-> [C=1.00,E=9]-> [C=1.00,E=9]->
Here ch_st is my character stack and dbl_st is my double stack
class conversion_and_solution{
public static String postfix = "";//taken a string for the output
public boolean isOperand(char c){//checks weather it is operand or not
if(c>='0'&&c<='9')
return true;
return false;
}
public boolean isOperator(char c){//checks weather operator
if(c=='+'||c=='*'||c=='/'||c=='-')
return true;
return false;
}
public int Opweight(char op){//checks Operator weight
int op_wt = 0;
switch(op){
case '+':{
op_wt = 1;
break;
}
case '-':{
op_wt = 1;
break;
}
case '/':{
op_wt = 2;
break;
}
case '*':{
op_wt = 2;
break;
}
default:{
System.out.println("Not Operator");
break;
}
}
return op_wt;
}
public boolean HigherPrecedence(char op1,char op2){//checks the precedence
int p_op1 = Opweight(op1);
int p_op2 = Opweight(op2);
if(p_op1>p_op2)
return true;
return false;
}
public String convert_to_postfix(String expression){//this is for converting infix to postfix
char []chr = new char[expression.length()];
char_stack ch_st = new char_stack();//object of character stack
String ss = " ";
for(int i=0;i<expression.length();i++){
chr[i] = expression.charAt(i);
//Now simple condition for checking weather Operand , Operator etc and doing the job
if(isOperator(chr[i])){
while(!ch_st.isEmpty()&&ch_st.char_top()!='('&&HigherPrecedence(ch_st.char_top(),chr[i])){
postfix= postfix+ch_st.char_top();
ch_st.char_pop();
}
ch_st.char_push(chr[i]);
}
else if(isOperand(chr[i])){
postfix = postfix + chr[i];
}
else if(chr[i]=='('){
ch_st.char_push(chr[i]);
}
else if(chr[i]==')'){
while(!ch_st.isEmpty()&&ch_st.char_top()!='('){
postfix = postfix + ch_st.char_top();
ch_st.char_pop();
}
ch_st.char_pop();
}
}
while(!ch_st.isEmpty()){//till not empty will pop the value and make the stack empty giving the output
postfix = postfix + ch_st.char_top();
ch_st.char_pop();
}
return postfix;
}
public double solve_eqns(){
char []ch = new char[postfix.length()];
double_stack dbl_st = new double_stack();
double result;
for(int i=0;i<postfix.length();i++){
ch[i] = postfix.charAt(i);
if(isOperand(ch[i])){//Checks for Operand
double x = Character.getNumericValue(ch[i]);
dbl_st.dbl_push(x);
dbl_st.dbl_display();
}
//Now if tey are operators the task is performed
if(isOperator(ch[i])){
if(ch[i]=='/'){
double d1 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double d2 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double temp = d2/d1;
dbl_st.dbl_push(temp);
}
else if(ch[i]=='*'){
System.out.println("\n\nOperation to be done:*");
double d1 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double d2 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double temp = d2*d1;
dbl_st.dbl_push(temp);
}
else if(ch[i]=='+'){
System.out.println("\n\nOperation to be done:+");
double d1 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double d2 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double temp = d2+d1;
dbl_st.dbl_push(temp);
}
else if(ch[i]=='-'){
System.out.println("\n\nOperation to be done:-");
double d1 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double d2 = dbl_st.dbl_top();
dbl_st.dbl_pop();
double temp = d2-d1;
dbl_st.dbl_push(temp);
}
}
}
result = dbl_st.dbl_top();
dbl_st.dbl_pop();
dbl_st.dbl_display();
System.out.println("\nOutput:"+result);
return result;
}
}
Here I am trying to solve an Infix Equation and I am getting false output as my code is considering every operator or operand as a character...
For example
If expression is (7+9)*4-12 gives correct output 52.
But if expression is (17+2)*4 then error occurs... it takes 7 and 1 as different numbers hence false output
So I want to know what changes in the code can make the inputs greater than 10 work properly
Here I am also not able to deal with unary operators
My advice is to revise your logic to take a more traditional approach of splitting lexical and semantic analysis. This will make your code more straightforward and easier to maintain than going directly from characters to interpretation.
However if you need to stick to your current approach then there is a relatively easy answer. In the code that processes operands you can continue to process numeric characters and add them as digits:
if (isOperand(ch[i])){
double x = Character.getNumericValue(ch[i]);
while (i < postFix.length() && isOperand(ch[i+1])) {
x = 10 * x + Character.getNumericValue(ch[++i]);
}
dbl_st.dbl_push(x);
dbl_st.dbl_display();
}
Though, as mentioned above, I would not recommend this approach. Much better is to convert to tokens before attempting to analyse semantics.
private class InputListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
String input = inputTextField.getText();
StringTokenizer strToken = new StringTokenizer(input, " ", false);
while (strToken.hasMoreTokens())
{
String i = strToken.nextToken();
int operand;
char operator;
try
{
operand = Integer.parseInt(i);
operandStack.push(operand);
}
catch (NumberFormatException nfe)
{
operator = i.charAt(0);
operatorStack.push(operator);
}
}
int result = sum (operandStack, operatorStack);
resultTextField.setText(Integer.toString(result));
}
My prefix expression code will only evaluate one expression at a time (i.e. + 3 1). I want it to evaluate multiple expressions in one user-input expression (i.e. * + 16 4 + 3 1). How can I edit the code provided to make it evaluate multiple expressions? Thank you for your help.
To simply make your program do a bit more you can use a loop to keep operating on the operandStack and pushing the result of the previous result to the stack. I left my println statements in so you can see what its doing. Also I modified your method so it can sit inside a standalone main method.
You should look into the Shunting-yard algorithm, its quite fun to implement and it is somewhat like what your doing here. http://en.wikipedia.org/wiki/Shunting-yard_algorithm
public static void main(String[] args) {
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
String input = "12 + 13 - 4";
StringTokenizer strToken = new StringTokenizer(input, " ", false);
while (strToken.hasMoreTokens()) {
String i = strToken.nextToken();
int operand;
char operator;
try {
operand = Integer.parseInt(i);
operandStack.push(operand);
} catch (NumberFormatException nfe) {
operator = i.charAt(0);
operatorStack.push(operator);
}
}
// loop until there is only 1 item left in the operandStack, this 1 item left is the result
while(operandStack.size() > 1) {
// some debugging println
System.out.println("Operate\n\tbefore");
System.out.println("\t"+operandStack);
System.out.println("\t"+operatorStack);
// perform the operations on the stack and push the result back onto the operandStack
operandStack.push(operate(operandStack, operatorStack));
System.out.println("\tafter");
System.out.println("\t"+operandStack);
System.out.println("\t"+operatorStack);
}
System.out.println("Result is: " + operandStack.peek());
}
/**
* Performs math operations and returns the result. Pops 2 items off the operandStack and 1 off the operator stack.
* #param operandStack
* #param operatorStack
* #return
*/
private static int operate(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop();
Integer a = operandStack.pop();
Integer b = operandStack.pop();
switch(op) {
case '-':
return b - a;
case '+':
return a + b;
default:
throw new IllegalStateException("Unknown operator '"+op+"'");
}
}
I left the operate method (previously called sum) as close to what you had it as possible, however I think that your code could be improved by simply passing 2 integers and a operator to the function. Making the function alter your stacks isnt a great thing and could lead to confusing problems.
Consider making your method signature this instead:
private static int operate(Integer a, Integer b, char operator) {
switch(operator) {
case '-':
return b - a;
case '+':
return a + b;
default:
throw new IllegalStateException("Unknown operator '"+operator+"'");
}
}
and then popping from the stack and passing those to the method. Keeping your stack altering code all in one place.
operandStack.push(operate(operandStack.pop(), operandStack.pop(), operatorStack.pop()));
I need some help on this one as I couldnt find a logical explanation for this anywhere. Maybe it is just a small mistake but I have been at the code for such a long time that I just cant see it. I have added comments where I am trying to push elements in my stack. I have two stacks one for all the operators and one for operands. The operator stack works fine but the operand stack is behaving weird. When I am trying to push elements it somehow replaces the stack elements with the latest element that I push. Whn I pop it returns the last element at all times. I have two different classes as operators and operands. Please let me know if you need the code for it. EDIT: The other classes dont do anything much though just a couple of getters, setters and checking for validity of tokens. Any help is appreciated. Thanks!
import java.util.*;
public class Evaluator {
private Stack<Operand> opdStack;
private Stack<Operator> oprStack;
public Evaluator() {
opdStack = new Stack<Operand>();
oprStack = new Stack<Operator>();
// HashMap<String, Operator> operators = new HashMap<String, Operator>();
Operator.operators.put("+",new AdditionOperator());
Operator.operators.put("-", new SubtractionOperator());
Operator.operators.put("*",new MultiplyOperator());
Operator.operators.put("/",new DivisionOperator());
Operator.operators.put("#",new BogusHash());
}
public int eval(String expr) {
String tok = "";
// init stack - necessary with operator priority schema;
// the priority of any operator in the operator stack other then
// the usual operators - "+-*/" - should be less than the priority
// of the usual operators
Operator newOpr = Operator.operators.get("#");
oprStack.push(newOpr);
String delimiters = "+-*/#! ";
StringTokenizer st = new StringTokenizer(expr,delimiters,true);
// the 3rd arg is true to indicate to use the delimiters as tokens, too
// but we'll filter out spaces
while (st.hasMoreTokens()) {
if ( !(tok = st.nextToken()).equals(" ")) { // filter out spaces
//System.out.println("equals");
if (Operand.check(tok)) { // check if tok is an operand
//System.out.println("tokens = "+tok);
//opdStack.push(new Operand ("0"));
opdStack.push(new Operand(tok));
System.out.println("stack peek "+ opdStack.peek().getValue());
//System.out.println(opdStack);
//System.out.println(oprStack);
} else {
//System.out.println("tokens = "+tok);
//System.out.println(newOpr);
if (!Operator.operators.containsKey(tok)) {
//System.out.println("tokens = "+tok);
//System.out.println(newOpr);
System.out.println("*****invalid token******"); System.exit(1);
}
Operator newOpr2 = Operator.operators.get(tok); // POINT 1
//System.out.println("Operator = "+oprStack.peek().priority());
while ( (oprStack.peek()).priority() >= newOpr2.priority()) {
//System.out.println("tokens while = "+tok);
System.out.println("tokens = "+tok);
Operator oldOpr = ((Operator)oprStack.pop());
//System.out.println("Opr"+oldOpr.priority());
Operand op2 = (Operand)opdStack.pop();
Operand op1 = (Operand)opdStack.pop();
System.out.println("run till here");
opdStack.push(oldOpr.execute(op1,op2));
System.out.println("Final res pushed opd= " + opdStack.peek().getValue());
}
oprStack.push(newOpr2);
//System.out.println("operand "+opdStack.toString());
}
}
}
//System.out.println("pop op2 = "+opdStack.pop().getValue()+" and pop op1 = "+opdStack.pop().getValue());
Operator newOp2 = ((Operator)oprStack.pop());
Operand op2 = (Operand)opdStack.get(0);
Operand op1 = (Operand)opdStack.get(1);
System.out.println("opd = "+ op1.getValue() + op2.getValue());
opdStack.push(newOp2.execute(op2, op1));
System.out.println("Full Stack opd size= "+ opdStack.size());
//System.out.println("Full Stack opd= "+ opdStack.toString());
Operand res = (Operand) opdStack.pop();
return res.getValue();
}
}
My Operand.java class
public class Operand {
static int val=0;
private static String strval="";
public Operand(String tok) {
// TODO Auto-generated constructor stub
strval = tok;
val = Integer.parseInt(strval);
// System.out.println("value = "+val);
}
public Operand(int value){
val = value;
//System.out.println("value = "+val);
}
public static boolean check(String tok) {
// TODO Auto-generated method stub
boolean bool;
try {
Integer.parseInt(tok);
bool = true;
} catch (Exception e){
//System.out.println("Type conversion "+e);
bool = false;
}
return bool;
}
public int getValue(){
//int re = Integer.parseInt(this.toString());
System.out.println("return value = " + val);
return val;
}
}
static String convert(String exp)
{
String result="";
Stack s1=new Stack();
for(int i=0;i<exp.length();i++)
{
if(Character.isDigit(exp.charAt(i)))
{{
result=result+exp.charAt(i);
continue;
}
else
{
if(s1.empty())
{
s1.push(exp.charAt(i));
continue;
}
else
{
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
s1.push(exp.charAt(i));
else
{
while(!s1.empty())
{
String a=s1.pop().toString();
result=result+a;
}
s1.push(exp.charAt(i));
}
}
}
}
while(!s1.empty())
{
String p=s1.pop().toString();
result=result+p;
}
return result;
}
static int check(char c)
{
switch (c) {
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
case '^':
return 2;
default:
throw new IllegalArgumentException("Operator unknown: " + c);
}
}
Here's my code to convert an expression from infix to postfix.
This code is working fine with just 2 operands..for more than 2 operands like 6+9*7 it shows
IllegalArgumentException which I have given in another method to set priorities of operators. Please help me to clarify where am I getting wrong?
Indent your code
In the stack trace:
at Test.convert(Test.java:21)
Is this line:
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
So I think you mean:
if (check(exp.charAt(i)) > check(s1.peek()))
Now "The method check(char) in the type Test is not applicable for the arguments (Object)" is raised, so parameterized your Stack. That is, change:
Stack s1=new Stack();
To (in Java 7):
Stack<Character> s1 = new Stack<>();
You are getting this exception because of your logic. Consider 1+2*3. In this case, when you get 3 below code gets executed:
else
{
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
s1.push(exp.charAt(i));
And check(3) results in
default:
throw new IllegalArgumentException("Operator unknown: " + c);