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 = "".
Related
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);
}
I have the program working except for the capitalization part:
Here's how to translate the English word englishWord into the Pig Latin word pigLatinWord:
a. If there are no vowels in englishWord, then pigLatinWord is just englishWord + "ay". (There are ten vowels: 'a', 'e', 'i', 'o', and 'u', and their uppercase counterparts.)
b. Else, if englishWord begins with a vowel, then pigLatinWord is just englishWord + "yay".
c. Otherwise (if englishWord has a vowel in it and yet doesn't start with a vowel), then pigLatinWord is end + start + "ay", where end and start are defined as follows:
1. Let start be all of englishWord up to (but not including) its first vowel.
2. Let end be all of englishWord from its first vowel on.
3. But, if englishWord is capitalized, then capitalize end and "uncapitalize" start.
How do you do the capitalization part?
So far, I get Hasta= astaHay. It should be Hasta = Astahay
Here is the basic program so far:
public static boolean isVowel(char c) {
if (c == 'a' && c == 'A') {
return true;
} else if (c == 'e' && c == 'E') {
return true;
} else if (c == 'i' || c == 'I') {
return true;
} else if (c == 'o' || c == 'O') {
return true;
} else if (c == 'u' || c == 'U') {
return true;
} else {
return false;
}
}
public static String convertPigLatinWord(String englishWord) {
int length = englishWord.length();
if (englishWord.charAt(length - 1) == '.' && englishWord.charAt(length - 1) == '!' && englishWord.charAt(length - 1) == '?') {
char ch = englishWord.charAt(0);
String rest = englishWord.substring(1, length - 1);
return (rest + ch + "ay" + englishWord.charAt(length - 1) + "\"" + " ");
} else if (isVowel(englishWord.charAt(0))) {
return (englishWord + "yay" + " ");
} else {
char ch = englishWord.charAt(0);
String rest = englishWord.substring(1);
return (rest + ch + "ay" + " ");
}
}
public String translate() {
String pigLatinPhrase = "";
while (englishPhrase.length() > 1) {
String word = getWord();
pigLatinPhrase += convertPigLatinWord(word) + " ";
}
return pigLatinPhrase;
}
public static void main(String[] args) {
String answer = "";
do {
Scanner keyboard = new Scanner(System.in);
String input;
System.out.print("Please enter an English phrase: ");
input = keyboard.nextLine();
PigLatin3 first = new PigLatin3(input);
System.out.println(first.translate());
System.out.println("Would you like to translate another phrase? (y or n)");
answer = keyboard.nextLine();
} while (!(answer.equals("N")) && !(answer.equals("n")));
System.exit(0);
}
}
You can capitalize a letter by breaking the string to substrings and then capitalizing them:
String word = word.substring(0, 1).toUpperCase() + word.substring(1);
So just use the toUpperCase() and toLowerCase() methods of String ...
There is also a neat trick that you can use with single characters based on the ASCII table. Just xor them with 32 to get the other case.
What you are looking for is something like this:
public static String onlyFirstLetterUpperCase(String a){
int i;
for (i = 0; i < a.length(); i++){
if("AEIOUaeiou".indexOf(a.charAt(i)) != -1 )
break;
// indexOf looks for a char in a given string and returns its
// position or -1 if not found. So if this indexOf returns -1 I can be sure,
// that the character is not a vowel
}
return a.substring(0, i + 1).toUpperCase() + a.substring(i + 1).toLowerCase();
}
Just call this method after performing your operations
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;
}