I have been working on a program for infix to postfix conversion and have everything working except that I cannot figure out where to put an error check for a missing left parenthesis. Basically the user inputs a String and the program goes to this class and converts it but I want to make sure they have entered the correct amount of parenthesis. I have tried multiple places but keep coming up with EmptyStackExceptions.
import java.util.*;
public class PostfixConversion {
public static boolean precedence(char first, char second)
{
int v1 = 0, v2 = 0;
//find value for first
if(first == '-' || first == '+'){
v1 = 1;
}else if(first == '*' || first == '/'){
v1 = 2;
}//end if
//find value for second
if(second == '-' || second == '+'){
v2 = 1;
}else if(second == '*' || second == '/'){
v2 = 2;
}//end if
if(v1 < v2){
return false;
}//end if
return true;
}//end precedence method
//converts infix expression into postfix expression
public static String convertToPostfix(String infixExp)
{
String postFix = "The Postfix Expression is: ";
Stack<Character> stack = new Stack<Character>();
char character = ' ';
for(int i = 0; i < infixExp.length(); i++)
{
character = infixExp.charAt(i);
//determine if character is an operator
if(character == '*' || character == '-' || character == '/' || character == '+')
{
while(!stack.empty() && precedence(stack.peek(), character)){
postFix += stack.pop();
}//end while
stack.push(character);
}
else if(character == '(') //check for left parenthesis
{
stack.push(character);
}
else if (character == ')')
{
while(!stack.peek().equals('(') && !stack.isEmpty()){ //add characters until left parenthesis
postFix += stack.pop();
}//end while
if(!stack.isEmpty() && stack.peek().equals('(')){
stack.pop(); // pop/remove left parenthesis
}
}
else
{
postFix += character;
}//end if
}//end for
while(!stack.empty()) //add the remaining elements of stack to postfix expression
{
if(stack.peek().equals('('))
{
postFix = "There is no matching right parenthesis.";
return postFix;
}
postFix += stack.pop();
}
return postFix;
}//end convertToPostfix
}
First of all, you have to change your while loop to this form:
while (!stack.empty() && precedence(stack.peek(), character)) {
postFix += stack.pop();
}
i.e. change order of expressions in while's check: stack.empty() check should be the first.
Second fix will be addition of "There is no matching left parenthesis." error message here:
if (!stack.isEmpty() && stack.peek().equals('(')) {
stack.pop(); // pop/remove left parenthesis
} else {
postFix = "There is no matching left parenthesis.";
return postFix;
}
Related
We are making a program to convert an input from infix to postfix. This is my code:
import javax.swing.*;
import java.util.Stack;
public class InfixToPostfix
{
public static int Precedence(char c)
{
return switch (c) {
case '+', '-' -> 1;
case '*', '/' -> 2;
default -> -1;
};
}
public static boolean isOp(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/';
}
public static void convert()
{
JFrame f;
f = new JFrame();
String eq = JOptionPane.showInputDialog("Enter Equation");
Stack<Character> stack = new Stack<>();
String postfix = "";
String numberInProgress = "";
for(int i=0; i<eq.length(); i++)
{
char c = eq.charAt(i);
if(Character.isDigit(c))
{
numberInProgress += c;
}
if(i>0 && Character.isDigit(eq.charAt(i-1)) && !Character.isDigit(c))
{
postfix += numberInProgress;
}
if(Character.isLetter(c))
postfix += (c + " ");
else if(isOp(c)) //Performs operator precedence stack checking/pushing/adding to String
{
if(stack.isEmpty())
stack.push(c);
else if(Precedence(c) > Precedence(stack.peek()))
stack.push(c);
else if(Precedence(c) <= Precedence(stack.peek()))
{
postfix += (stack.pop() + " ");
stack.push(c);
}
}
else if(c == '(' || c == '[' || c == '{') //This else if and while perform the actions when a set of paranthesis is completed
stack.push(c);
while((c == ')' && stack.peek() != '(') || (c == ']' && stack.peek() != '[') || (c == '}' && stack.peek() != '{') )
{
if(stack.peek()=='(' || stack.peek()=='[' || stack.peek()=='{' )
stack.pop();
else
postfix += (stack.pop() + " ");
}
}
if(stack.peek()=='(' || stack.peek()=='[' || stack.peek()=='{' ) //Simply removes if the top of the stack is a parenthesis
stack.pop();
for (int i = 0; i <=stack.size() ; i++) //Finishes of the stack once the string is finished being iterated through
{
if(stack.peek()=='(' || stack.peek()=='[' || stack.peek()=='{' )
stack.pop();
if(stack.size()==0)
break;
postfix += (stack.pop() + " ");
}
JOptionPane.showMessageDialog(f, postfix);
}
public static void main(String[] args)
{
convert();
}
}
it works with variables and numbers that are only one digit but if i want to do 12+3, it would output 1 2 3+ when I really want it to output 12 3 + I then need to make a calculator to calculate the postfix string but I think that would be easier than what I am trying to do right now. I just need to somehow get this to recognize numbers that are more than one digit. UPDATE: I tried to do what Ian Mc suggested and I am so close but I just cannot figure it out. 12+3 with this current code outputs 12+ so I can get it to recognize double digits at least
You are not able to process multi-digit numbers because you don't maintain the state of the number as you read the equation character by character. The following code is the root of the problem:
if(Character.isLetterOrDigit(c))
postfix += (c + " ");
One way to maintain state is to introduce a new variable: String numberInProgress = "";
If you process a digit, you change the state: numberInProgress += c;. You do not process the number at this point; go on and read the next character from the equation.
When you hit any character that is not a number (a bracket, operation, space), you finalize numberInProgress, and proceed to process it. After that, reset numberInProgress = "".
My assignment is: if the user-inputted word has no vowels, then "ay" is added to the end, if it starts with a vowel then it adds "yay" to the end, otherwise if it doesn't meet any of these conditions then the first letter gets moved to the end of the word and "ay" is added to the end. I can't seem to get the last condition to work. For example the word "sad" should output "adsay" but instead it outputs "saday" which means that it is reading and accepting another if statement. I've tried to look up some solutions but all I've gotten are loops and I'd like to avoid loops for this particular assignment. Here is my code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Word: ");
String word = in.nextLine();
int length = word.length();
String word1 = "";
if (word.charAt(0) == 'a' || word.charAt(0) == 'e' || word.charAt(0) == 'i' || word.charAt(0) == 'o' || word.charAt(0) == 'u')
{
word1 = pigLatin(word);
System.out.println("Pig Latin: " + word1);
}
else if (word.indexOf("a") == -1 || word.indexOf("e") == -1 || word.indexOf("i") == -1 || word.indexOf("o") == -1 || word.indexOf("u") == -1)
{
word1 = pigLatin1(word);
System.out.println("Pig Latin: " + word1);
}
else
{
word1 = pigLatin2(word);
System.out.println("Pig Latin: " + word1);
}
}
static String pigLatin(String word)
{
String x = word + "yay";
return x;
}
static String pigLatin1(String word)
{
String x = word + "ay";
return x;
}
static String pigLatin2(String word)
{
char firstLetter = word.charAt(0);
String x = word.substring(1, word.length()) + firstLetter + "ay";
return x;
}
}
The problem lies in your second if statement:
else if (word.indexOf("a") == -1 || word.indexOf("e") == -1 || word.indexOf("i") == -1 || word.indexOf("o") == -1 || word.indexOf("u") == -1)
{
word1 = pigLatin1(word);
System.out.println("Pig Latin: " + word1);
}
Because you're using "or" here (the || operator), your program will enter this block as long as the word doesn't contain "a", or doesn't contain "e", etc. For your test input, "sad" contains "a" but it doesn't contain "e"... so you wind up calling pigLatin1("sad").
Change this if to use "and" instead (the && operator). That way, the word will need to not have every defined vowel, instead of not having at least one defined vowel.
else if (word.indexOf("a") == -1 && word.indexOf("e") == -1 && word.indexOf("i") == -1 && word.indexOf("o") == -1 && word.indexOf("u") == -1)
My code successfully converts an infix expression to postfix expression. However, when I enter a number that is more than 1 digit (e.g. 546) I get no spaces between this number and the right operand.
A test run of my code:
Input: Enter an expression: (24/4) / (15/3) * 10 - 4 + 2
Output: The Postfix Expression is: 244/ 153/ / 10 * 4 - 2+
I'd like it to be The Postfix Expression is: 24 4/ 15 3/ / 10 * 4 - 2+
This is my code: Please suggest any changes that will allow me to insert spaces in the output.
import java.util.*;
public class PostfixConversion {
public static void main(String args[]) {
System.out.print("Enter an expression: ");
String infix = new Scanner(System.in).nextLine();
System.out.println(convertToPostfix(infix));
}
public static boolean precedence(char first, char second)
{
int v1 = 0, v2 = 0;
//find value for first
if(first == '-' || first == '+'){
v1 = 1;
}else if(first == '*' || first == '/'){
v1 = 2;
}//end if
//find value for second
if(second == '-' || second == '+'){
v2 = 1;
}else if(second == '*' || second == '/'){
v2 = 2;
}//end if
if(v1 < v2){
return false;
}//end if
return true;
}//end precedence method
//converts infix expression into postfix expression
public static String convertToPostfix(String infixExp)
{
String postFix = "The Postfix Expression is: ";
Stack<Character> stack = new Stack<Character>();
char character = ' ';
for(int i = 0; i < infixExp.length(); i++)
{
character = infixExp.charAt(i);
//determine if character is an operator
if(character == '*' || character == '-' || character == '/' || character == '+')
{
while(!stack.empty() && precedence(stack.peek(), character)){
postFix += stack.pop();
}//end while
stack.push(character);
}
else if(character == '(') //check for left parenthesis
{
stack.push(character);
}
else if (character == ')')
{
while(!stack.peek().equals('(') && !stack.isEmpty()){ //add characters until left parenthesis
postFix += stack.pop();
}//end while
if(!stack.isEmpty() && stack.peek().equals('(')){
stack.pop(); // pop/remove left parenthesis
}
}
else
{
postFix += character;
}//end if
}//end for
while(!stack.empty()) //add the remaining elements of stack to postfix expression
{
if(stack.peek().equals('('))
{
postFix = "There is no matching right parenthesis.";
return postFix;
}
postFix += stack.pop();
}
return postFix;
}//end convertToPo
}
The fix is to add a line here (see code comment):
if(character == '*' || character == '-' || character == '/' || character == '+')
{
postFix += ' '; // <-- add space here
while(!stack.empty() && precedence(stack.peek(), character)){
postFix += stack.pop();
}//end while
stack.push(character);
}
after applying the fix the output on my machine looks like:
The Postfix Expression is: 24 4/ 15 3/ / 10 * 4 - 2+
The problem asks to compare if the string has consecutive same letters and rewrite it as the number of the letter plus the letter, for example, AAAAA as in 5A. But when I use the if statement to make the comparison the output become some very long number instead of the desired result.
Here is a portion of the problem:
Run-length encoding is a simple compression scheme best used when a dataset consists primarily of numerous, long runs of repeated characters. For example, AAAAAAAAAA is a run of 10 A’s. We could encode this run using a notation like *A10, where the * is a special flag character that indicates a run, A is the symbol in the run, and 10 is the length of the run.
Here is the code:
import java.util.Scanner;
public class RunLengthEncoding {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter input string: ");
String s = input.nextLine();
for (int a = 0; a < s.length(); a++) {
if ((s.charAt(a) < 'A' || s.charAt(a) > 'Z')) {
System.out.print("Bad input");
System.exit(0);
}
}
System.out.print("Enter flag character: ");
char flag = input.nextLine().charAt(0);
if (flag == '#' || flag == '$' || flag == '*' || flag == '&') {
int count = 0;
for (int i = 1; i < s.length(); i++) {
if(s.charAt(i)=s.charAt(i-1));
count++;
if (count == 1)
System.out.print(s.charAt(i));
if (count == 2)
System.out.print(s.charAt(i) + s.charAt(i));
if (count == 3)
System.out.print(s.charAt(i) + s.charAt(i) + s.charAt(i));
else
System.out.print(flag + s.charAt(i) + (count + 1));
}
} else
System.out.print("Bad input");
}
}
Your problem is here:
if(s.charAt(i)=s.charAt(i-1));
First of all, you must compare chars using == not =. Second, putting a ; right after the if statement will cause it to terminate immediately. In other words, the following line is no longer part of the if statement. Change to:
if(s.charAt(i) == s.charAt(i-1))
Edit
Regarding your comment, something like this should work, though I didn't test it. Just replace your current large if block with the below:
if (flag == '#' || flag == '$' || flag == '*' || flag == '&') {
char last = ' ';
char curr = ' ';
int count = 1;
for (int i = 0; i < s.length(); i++) {
last = curr;
curr = s.charAt(i);
if (curr == last) {
count++;
} else if (last != ' ') {
System.out.print(("" + count) + last);
count = 1;
}
}
System.out.print(("" + count) + last);
}
String input = "a == b";
for(int i = 0; i < input.length(); i++){
char c = input.charAt(i);
if(c == '='){
System.out.println("Assignment Operator");
}
}
In the above example if character is '=' and the next character is also '=' then print Comparison Operatorotherwise print Assignment Operator
You can do something like this
for(int i = 0; i < input.length() - 1; i++){
if(input.charAt(i) == '=') {
if(input.charAt(i + 1) == '=') {
System.out.println("Comparison Operator");
}
else {
System.out.println("Assignment Operator");
}
break;
}
}
The solution is simple:
if(input.charAt(input.indexOf("=") + 1) == '='){
System.out.println("Comparison Operator");}else{
System.out.println("Assignment Operator");
}
You can either use the strings class substring method, or the charAt method or you could use the contains these all would allow you to do what you want.