Java Infix / Postfix Converter with Stacks - java

I'm supposed to implement 3 functions in the following code.
Functions:
1. evaluate arithmetic expression in postfix
2. convert arithmetic expression from infix to postfix
3. convert arithmetic expression from postfix to infix
I don't know at all where I could start and how the functions need to look / made up at all. If you could help me with just one of these 3 functions, I would probably be able to do the other 2 myself.
Here is the code:
import java.util.Stack;
public class Postfix {
public static int evalPostfix(String postfix) {
// TODO
}
public static String infixToPostfix(String infix) {
// TODO
}
public static String postfixToInfix(String postfix) {
// TODO
}
public static void main(String[] args) {
String infix1 = "(3-(7*2))";
String postfix1 = "372*-";
int eval1 = -11;
String infix2 = "((7+1)*((3-6)*(5-2)))";
String postfix2 = "71+36-52-**";
int eval2 = -72;
System.out.println(" postfix1: " + postfix1);
int n = evalPostfix(postfix1);
System.out.println("evalPostfix(postfix1): " + n);
if (n == eval1) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
System.out.println(" infix1: " + infix1);
String s = infixToPostfix(infix1);
System.out.println("infixToPostfix(infix1): " + s);
if (s.equals(postfix1)) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
System.out.println(" postfix1: " + postfix1);
s = postfixToInfix(postfix1);
System.out.println("postfixToInfix(postfix1): " + s);
if (s.equals(infix1)) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
System.out.println(" postfix2: " + postfix2);
n = evalPostfix(postfix2);
System.out.println("evalPostfix(postfix2): " + n);
if (n == eval2) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
System.out.println(" infix2: " + infix2);
s = infixToPostfix(infix2);
System.out.println("infixToPostfix(infix2): " + s);
if (s.equals(postfix2)) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
System.out.println(" postfix2: " + postfix2);
s = postfixToInfix(postfix2);
System.out.println("postfixToInfix(postfix2): " + s);
if (s.equals(infix2)) {
System.out.println(" Right!");
} else {
System.out.println(" Wrong!");
}
System.out.println();
}
}

Here is some incomplete pseudocode to help you:
function int evalPostfix(string postfix)
repeat
// Fetch the next item.
item <- get next item from postfix
// Process the current item.
if (item is operand)
push item onto stack
else if (item is operator)
pop required number of operands from the stack
push operator(operands) onto stack
else
throw error "Unrecognised item: " + item + " found."
end if
until (no more items in postfix)
return pop from stack
end function
You will need separate operator functions for each operator that your code needs to deal with.

This is a classic 'Stack' data structure problem.
May be you have already given it a try with Stacks (you have a stack import.), you can also solve that with regular expressions or binary trees etc,
in case you just want an idea to solve that, hope this may help:
infix to postfix conversion with stacks:
Algorithm:
Scan the input infix expression from left to right.
If that's an operand add it to your temporary string.
else if the order of precedence of the operator is more than the operator in stacks or stack is empty then push it to stack.
If it is '(', add that to stack.
else if it is ')', pop and add item to output string until an '(' comes.
keep doing 2-5 util string have more characters.
static Stack<String> stack;
private static String doInfixToPostfix(String exp) {
stack = new Stack<String>();
String output = "";
for(int i=0;i<exp.length();i++){
if(exp.charAt(i) == '('){
stack.push("(");
}
else if(exp.charAt(i) == ')'){
while(stack.size()>0 && stack.peek() != "("){
output+= stack.pop();
}
if(stack.size()>0 && stack.peek() != "(")
return "INVALID";
else
stack.pop();
}
else if(isOperand("" + exp.charAt(i))){
//Its a Number
//It could be replaced to get more than one digits.....
output+= exp.charAt(i);;
}
else{
//Its a operator
while(stack.size()>0 && (priority("" + exp.charAt(i)) < priority(stack.peek()))){
output += stack.pop();
}
stack.push("" + exp.charAt(i));
}
}
while(stack.size()>0){
output+=stack.pop();
}
return output;
}
private static int priority(String value) {
if(value == "+" || value == "-") return 1;
else if(value == "*" || value == "/") return 2;
else if(value == "^") return 3;
return 0;
}
//This could be modified to accept more than one digits...
private static boolean isOperand(String value) {
try{
Integer.parseInt(value);
}
catch(NumberFormatException e){return false;}
return true;
}
and hey, instead comparing outputs by those very long code blocks, you could have simply used assertEquals() test cases.

Related

How do I put a remove a leading space when printing something in java?

How do I put a remove a leading space when printing something in java?
import java.util.Scanner;
import java.io.IOException;
public class InitialsProject {
public static void main(String args[]) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scan.nextLine();
char firstInitial = name.charAt(0);
int index = name.indexOf(" ");
System.out.println(firstInitial + name.substring(index++,index+1));
}
}
Sample input: John Doe
Output: J D
So your question is a little vague, but I assume your issue is around "why does it print "J D" and not "JD""
The simple answer is index++ is post operation, that is, the value of index is first used (by substring), then it's updated. You could fix it by using a pre operation, ie ++index, but I would suggest that using index + 1 (and index + 2) is more readable and less error prone.
But...there are a number of ways you might perform this operation
For example, you could simply use String#split
String text = "John Doe";
String[] parts = text.split(" ");
if (parts.length == 1 && !parts[0].isEmpty()) {
System.out.println(parts[0].charAt(0));
} else if (parts.length == 2) {
if (!parts[0].isEmpty() && !parts[1].isEmpty()) {
System.out.println(parts[0].charAt(0) + " " + parts[1].charAt(0));
} else if (!parts[0].isEmpty()) {
System.out.println(parts[1].charAt(0));
} else if (!parts[1].isEmpty()) {
System.out.println("..." + parts[1].charAt(0));
} else {
System.out.println(text + " is an invalid input");
}
} else {
System.out.println(text + " is an invalid input");
}
nb: I'm been a little defensive, can't help it
Or you could simply use charAt directly...
int index = text.indexOf(" ");
if (index >= 0) {
if (index + 1 < text.length()) {
System.out.println(text.charAt(0) + " " + text.charAt(index + 1));
} else {
System.out.println(text.charAt(0));
}
} else {
// Handle all the other possible conditions
}
Both the examples will print J D
Simply using charAt would do the trick,
System.out.println(firstInitial + name.charAt(index+1));

Check whether the brackets and delimiters contained in a string are balanced

Here is simple code to check whether the brackets/delimiters contained in a string are balanced - can anyone help why wont it work! I'm sure there are many things I could to to improve efficiency but for the purpose of my current tutorial I would like to know why it doesn't work in this form and what the current problems are.
Firstly, I cannot add the variable c to the LinkedList, I have to use the literal value - I have identical in another tutorial and it adds the variable just fine.
Secondly, in some instances it simply doesn't add the delimiters to my linkedlist as per the if statements. the string '(i wonder(if) the delimiters in this) [sentence] will evaluate as[ balanced}' evaluates as balanced but from my code it shouldn't do - Please help I am pulling my hair out here.
Finally, I have had the same error but sporadically not for every string - some i type in randomly for example 'csadlkfsd kljf[]{}[ ][ ]{ '
this returned the error
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at set07102.Delimiter.main(Delimiter.java:16)
and line 16 is 'char c = s.charAt(0);' and as far as i see this shouldn't be happening.
System.out.println(strStack); is only there are at the end to inspect the LinkedList - if it makes it that far through the code!
any help will be amaaaaaaaaazing thanks guys.
import java.util.LinkedList;
import java.util.Scanner;
public class Delimiter {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a string containing different types of brackets: ");
String str = scanner.nextLine();
String[] strSplit = str.split(" ");
LinkedList<Character> strStack = new LinkedList<>();
System.out.println(" ");
for(String s : strSplit) {
char c = s.charAt(0);
if(c == '('){
strStack.push('(');
}
if( c == '{'){
strStack.push('{');
}
if(c == '['){
strStack.push('[');
}
if(c == '<'){
strStack.push('<');
}
if(c == ')' && strStack.get(0) != '('){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == ']' && strStack.get(0) != '['){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == '}' && strStack.get(0) != '{'){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
if(c == '>' && strStack.get(0) != '<'){
System.out.println("The delimiters in the string " + "'" + str + "'" + " are not balanced!");
break;
}
}
System.out.println("The delimiters in the string " + "'" + str + "'" + " are balanced. ");
System.out.println(" ");
System.out.println(strStack);
}
}
Here is one way of doing it. I'm not sure if it's completely bug free and will handle all cases, but I think it might be close.
As other users have commented, splitting the input string is the wrong approach. You'll need to iterate over each character and use the stack to keep track of what brackets you've seen and what should be closed next.
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;
public class BalancedBrackets
{
public static void main(String[] args)
{
HashMap<Character,Character> bracketPairs = new HashMap<Character,Character>();
bracketPairs.put('[', ']');
bracketPairs.put('(', ')');
bracketPairs.put('{', '}');
bracketPairs.put('<', '>');
Stack stack = new Stack();
Scanner scanner = new Scanner(System.in);
System.out.println("Please enter a string containing different types of brackets: ");
String str = scanner.nextLine();
for(int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if(bracketPairs.keySet().contains(c))
{
stack.push(c);
}
if(bracketPairs.values().contains(c))
{
if(stack.size() == 0)
{
System.out.println("Unexpected closing bracket.");
return;
}
char lastOpen = (char) stack.peek();
char expectedClose = bracketPairs.get(lastOpen);
if(expectedClose == c)
{
stack.pop();
}
else
{
System.out.println("Unexpected closing bracket.");
return;
}
}
}
if(stack.size()==0)
{
System.out.println("String is balanced.");
}
else
{
System.out.println("String is unbalanced.");
}
}
}

Java decToHex in recursive - wrong output order

I tried to check other questions close to this one, but couldn't figure out one answer for mine, that's why sending it as a new post. Hope this won't cause any problem.
I am trying to write a simple JAVA code for number conversion- from decimal to octal or hex. With octal everything is fine, but with hex, the output is in wrong order. like if the answer is 613 - program gives out 316.
Here is my full code:
import java.util.Scanner;
public class Cem {
public static void octalconverter(int a) {
if (a == 0) { //our base
System.out.println(); //I first put here return a, but then it was adding zeros to the end
} else {
System.out.print(a % 8);// first remainder = last digit, and so on
octalconverter(a / 8); //recursively going till it is base
}
}
public static void hexconverter(int a) {
if (a == 0) {
System.out.println();
} else {
System.out.print(hexchart(a % 16));
hexconverter(a / 16);
}
}
public static String hexchart(int a) {
String result = "";
if (a <= 9) {
result = a + result;
} else {
if (a == 10)
result = result + "A";
// System.out.print("A");
if (a == 11)
result = result + "B";
// System.out.print("B");
if (a == 12)
result = result + "C";
// System.out.print("C");
if (a == 13)
result = result + "D";
//System.out.print("D");
if (a == 14)
result = result + "E";
//System.out.print("E");
if (a == 15)
result = result + "F";
// System.out.print("F");
}
return result;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner oScan = new Scanner(System.in);
System.out.println("Please enter your decimal number : "); //getting input
int num = oScan.nextInt(); //assigning
System.out.println("Enter 1 for Octal Base Conversion #### Enter 2 for Hex Conversion");
int num2 = oScan.nextInt();
if (num2 == 1) {
System.out.print(num + " in Octal(base8) system is : ");
octalconverter(num); //conversion
} else if (num2 == 2) {
System.out.print(num + " in Hexadecimal(base16) system is : ");
hexconverter(num);
} else {
System.out.println("You entered a wrong choice for conversion type, please restart the program");
}
}
}
Can you please tell me where I messed up. I also must say I am looking for the mistake I did here, not another way of how to write this code. Thank you those who are willing to share another way of it, but again I need to learn my mistake here.
Thank you for your help
Change
public static void hexconverter(int a) {
if (a == 0) {
System.out.println();
} else {
System.out.print(hexchart(a % 16));
hexconverter(a / 16);
}
}
To
public static void hexconverter(int a) {
if (a == 0) {
System.out.println();
} else {
hexconverter(a / 16);
System.out.print(hexchart(a % 16));
}
}
Your octal conversion is also not working properly. It prints in reverse order. So just swapped those instructions also.
Bill Gates once said that he would always "hire a lazy person to do a difficult job" at Microsoft. ... "Because a lazy person will find an easy way to do it."
I know you said you aren't looking for another way of how to write this code but this is much easier way to get the job done.
public static String octalNumber = "";
public static void octalconverter(int a){
while(a!=0){
octalNumber = octalNumber + String.valueOf(a%8);
a = a/8;
}
System.out.println(new StringBuilder(octalNumber).reverse().toString());
}
Final number has to be reversed.That was a mistake.

if else statements returning null with boolean operator

this is my first time making a question so I'm not sure if my title is correct at all because I'm pretty new to java... basically my program is returning all null during the changeNameFormat method when there is no space in the name but what I want it to do is to print out "You do not have a space in your name" and then move onto the next method. Currently my code is as follows, and logically to me at least it makes sense, but I'm no expert.
import java.util.*;
public class Lab11 {
static String name, first, last, word;
static boolean space;
public static void main(String [] args) {
Scanner input = new Scanner(System.in);
System.out.println("Input your name: ");
name = input.nextLine();
changeNameFormat();
if (space = true) {
System.out.println("Your name is : " + first + " " + last);
System.out.println("Your first name is : " + first);
System.out.println("Your last name is : " + last);
}
else {
System.out.println("Your name contains no spaces");
}
System.out.println("Input word for palindrome test: ");
word = input.nextLine();
if (palindrome(word)) {
System.out.println(word + " is a palindrome");
}
else {
System.out.println(word + " is NOT a palindrome");
}
}
public static void changeNameFormat() {
if (name.contains(" ")) {
String [] split = name.split(" ", 2);
first = split[0];
String last = split[1];
space = true;
}
else {
space = false;
}
}
public static boolean palindrome(String w) {
System.out.println("Checking if " + word + " is a palindrome.");
System.out.println("... Loading...");
String reverse = "";
for (int i = w.length() - 1 ; i >= 0 ; i--) {
reverse = reverse + w.charAt(i);
}
if (w.equalsIgnoreCase(reverse)) { // case insensitive check
return true;
}
else {
return false;
}
}
}
A very small mistake out of negligence.
You have used a single equals assignment operator (=), which assigns true to space. If you want to check whether space is true, you need the double equals comparison operator (==):
if (space == true)
Note that a better, more idiomatic way of writing this is:
if (space)
Also your ChangeNameFormat() method localizes the last variable, in case you haven't noticed.

Math string with no spaces?

import java.util.Scanner;
public class Improved {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a number operaion number: ");
int operand1 = Integer.parseInt(input.nextLine());
char expo1 = input.next().charAt(0);
int operand2 = Integer.parseInt(input.nextLine());
System.out.println( operand1 + expo1 + operand2 + "=");
if ( expo1 == '/' && operand2 == '0' ){
System.out.println("Cannot divide by zero"); }
else
if (expo1 == '-') {
System.out.println(operand1-operand2);
} else
if (expo1 == '+') {
System.out.println(operand1+operand2);
} else
if (expo1 == '/') {
System.out.println(operand1/operand2);
} else
if (expo1 == '%') {
System.out.println(operand1%operand2);
}
else{
System.out.println(" Error.Invalid operator.");
}
}
}
//This bottom works, but I found out that this is not what is supposed to be done with this problem
/*
public class Else {
public static void main(String[] args) {
int operand1;
char exp1;
int operand2;
if (args.length != 3 ) {
System.err.println("*** Program needs 3 arguements***");
System.err.println("Usage: java Else int1 exp int2");
System.exit(1);
}
operand1 = Integer.parseInt(args[0]);
exp1 = args[1].charAt(0);
operand2 = Integer.parseInt(args[2]);
System.out.print(args[0] + args[1] + args[2] + "=");
if(exp1 == '-') {
System.out.println(operand1 - operand2);
} else
if (exp1 == '+') {
System.out.println(operand1 + operand2);
} else
if (exp1 == '/') {
System.out.println(operand1 / operand2);
} else
if (exp1 == '%') {
System.out.println(operand1 % operand2);
}
else{
System.out.println(" Error.Invalid operator.");
}
}
}
*/
What I want the program to do is ask one to enter a math operation 1/2 or 1%2 (not multiplication)
, but just like that without spaces. Still, I want to check which operation is being done which is why i put the if statements. What I don't get is how the program would know when an operation appears in a string. I'm not even sure if I set it correctly. Overall, I want a string that reads the number then the operation an then the number again. I'm sorry if this seems like doing my hw, but I have tried making this program multiple times, but can't understand how I can do this with a string. I wrote the second one to show that I have done this multiple times, so you can ignore it. Thank You very much!
read input as a String using:
String inputString = input.nextLine();
get the index of the operator:
int indexOp = inputString.indexOf("+");
if(indexOp < 0) indexOp = inputString.indexOf("-"); //cannot find +, so find -
if(indexOp < 0) indexOp = inputString.indexOf("/"); //cannot find -, so find /
if(indexOp < 0) indexOp = inputString.indexOf("%"); //cannot find /, so find %
get the first and second operand with:
int operand1 = Integer.parseInt(inputString.substring(0,indexOp));
int operand2 = Integer.parseInt(inputString.substring(indexOp+1,inputString.length());
get the operator from the indexOp we got earlier:
char operator = inputString.charAt(indexOp);
Hope it helps :)
I have no doubt there are a number of ways this might be achieved, this is simply another example...
What this tries to do, is break down the incoming text into groups of digits and non digits. It then loops through these groups making up the various elements of the calculation...
Scanner input = new Scanner(System.in);
System.out.println("Enter a number operaion number: ");
String text = input.nextLine();
System.out.println("Input = " + text);
text = text.replaceAll("\\s", "");
System.out.println("Parse = " + text);
Pattern p = Pattern.compile("\\d+|\\D+");
Matcher m = p.matcher(text);
int index = 0;
int op1 = -1;
int op2 = -2;
String exp1 = "";
while (index < 3 && m.find()) {
System.out.println(index);
String part = m.group();
switch (index) {
case 0:
op1 = Integer.parseInt(part);
break;
case 2:
op2 = Integer.parseInt(part);
break;
case 1:
exp1 = part;
break;
}
index++;
}
System.out.println(op1 + " " + exp1 + " " + op2);
What this does have, is the power to to allow you to supply a much longer calculation, for example 20+30/40-50...etc.
You would need to park each operand and exponent into some kind of List and extract them as you need them...or you could actually do the calculation directly within the while loop
Try this:
package week11;
import java.util.Scanner;
public class maths {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("enter a number ");
int x = scanner.nextInt();
System.out.println("put +, -, / or * ");
char expo1 = scanner.next().charAt(0);
System.out.println("second number please ");
int y = scanner.nextInt();
System.out.println( "Answer is" + ":");
if ( expo1 == '/' && y == '0' ){
System.out.println("cannot be divided by 0"); }
else
if (expo1 == '-') {
System.out.println(x-y);
} else
if (expo1 == '+') {
System.out.println(x+y);
} else
if (expo1 == '/') {
System.out.println(x/y);
} else
if (expo1 == '%') {
System.out.println(x%y);
}
else{
System.out.println(" Error!");
}
}
}
I would like to add another solution, which removes a lot of the parsing work.
import java.util.Scanner;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
class Scratch {
public static void main(String[] args) throws ScriptException {
System.out.println("Enter an operation:");
Scanner input = new Scanner(System.in);
String operation = input.nextLine();
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval(operation);
System.out.printf("%s = %s%n", operation, result);
}
}
sample result
Enter an operation:
2 + 3 * 4
2 + 3 * 4 = 14.0

Categories