Hi i am working on calculator but i am not getting correct output. For example with
4+(1/2)+8
The desired output is 12.5 but my code returns 12.0
i have used this code but this will no giving the rounded value
public String evaluatePostfix(String postfix){
LongStack S = new LongStack();
float resout;
//answer for val1 and val2
Dialog.alert("postfix: "+postfix + "length "+ postfix.length());
for(int k = 0; k < postfix.length(); k++)
{
char c =postfix.charAt(k);
if( c >= '0'&& c <= '9')//i < tokens.length && (Character.isDigit(tokens[i]) || tokens[i] == '.')
S.push((c - '0'));
else if (c == '+' || c== '-' || c == '*' || c == '/' || c == '%' || c == '~')
{
if(S.isEmpty()) throw new RuntimeException("Empty Stack");
float RightOp = S.pop();
Dialog.alert(": "+ RightOp);
if( c == '~') S.push( (long) -RightOp);
if(S.isEmpty()) throw new RuntimeException("Empty Stack.");
switch (c)
{
case '+' : S.push((long) (S.pop() + RightOp)); break;
case '-' : S.push((long) (S.pop() - RightOp)); break;
case '*' : S.push((long) (S.pop() * RightOp)); break;
case '/' : S.push((long) (S.pop()/ RightOp)); break;
case '%' : S.push((long) (S.pop() % RightOp)); break;
}// END of switch
}
else if ( c != ' ')throw new RuntimeException("Error!");
}
Dialog.alert(Long.toString(S.pop()));
Float fX = new Float(S.pop());
Formatter f = new Formatter();
String result = f.formatNumber(fX.floatValue(), 2);
return result;
}
The problem is since your storing the number as a long, you loose the decimal due to the data type. A better data type to use for storing decimals is a double as it allows decimals and has a range that should be more than enough for a calculator
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 = "".
I am making a calculator for school project. My problem is, that when I input e.g. 1 at op = sc.next().charAt(0);, the first if statement does its body, even if it's not true. Also, it doesn't return at the start of the loop, but the program ends. I'm still new at Java so that's why I'm here.
Also, I am open to any suggestions to make it better. :)
Thank you!
import java.util.Scanner;
public class Kalkulacka {
public static void main(String[] args) {
System.out.println("Vitajte v programe na výpočet jednoduchých matematických príkladov!");
Scanner sc= new Scanner(System.in);
double a;
char op = 0;
double b;
double priklad = 0;
int i=0;
System.out.println("Zadajte číslo");
a= sc.nextDouble();
priklad= a;
while (true) {
if (i<1) {
System.out.println("Zvoľte si operátora:");
System.out.println("1- +");
System.out.println("2- -");
System.out.println("3- *");
System.out.println("4- /");
op = sc.next().charAt(0);
if (op != 1 && op != 2 && op != 3 && op != 4) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
}
if (i>=1) {
System.out.println("Zvoľte si operátora:");
System.out.println("1- +");
System.out.println("2- -");
System.out.println("3- *");
System.out.println("4- /");
System.out.println("5- =");
op= sc.next().charAt(0);
if (op!=1 && op!=2 && op!=3 && op!=4 && op!=5) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
if (op==5) {
break;
}
}
System.out.println("Zadajte číslo");
b= sc.nextDouble();
if (i<1) {
switch (op) {
case 1:
priklad = a + b;
case 2:
priklad = a - b;
case 3:
priklad = a * b;
case 4:
priklad = a / b;
}
}
else {
switch (op) {
case 1:
priklad = priklad + b;
case 2:
priklad = priklad - b;
case 3:
priklad = priklad * b;
case 4:
priklad = priklad / b;
}
}
i=i++;
}
System.out.println("Výsledok je: "+priklad);
}
}```
A character is nothing but a number. That´s why you can compare a char with int as in your op != 1-check. However the appropriate number - the so-called ASCII-code - for '1' is not 1, but 49. 49 is surely not equal to 1, so your condition op != 1 matches.
Either check for op == 49 or just op == '1' (for the further checks you surely need the appropriate ASCII-codes 50, 51 and 52).
I think the problem is
op = sc.next().charAt(0);
if (op != 1 && op != 2 && op != 3 && op != 4) {
System.out.println("Zadali ste nesprávne číslo");
return;
}
Op is a char, so when you get the input from the user it's '1', '2', '3', '4' but you check equality with 1, 2, 3, 4. Condition is always true and the program returns.
My problem is, that when I input e.g. 1 at op = sc.next().charAt(0);,
the first if statement does its body, even if it's not true.
Replace
if (op != 1 && op != 2 && op != 3 && op != 4)
with
if (op != '1' && op != '2' && op != '3' && op != '4')
as you are comparing char values. If you want to compare with their ASCII values, you can use op != 49 and so on. Check https://ee.hawaii.edu/~tep/EE160/Book/chap4/subsection2.1.1.1.html
The same applies to your switch...case also i.e. you should use case '1' instead of case 1.
Also, it doesn't return at the start of the loop, but the program
ends.
Replace return with continue.
first question here so I'm not entirely sure on the right way of going about this but here goes:
So, I was looking for some simple code to Evaluate dynamic string expressions and found this great code here on Study.com but for some reason the Exponent ^ and Modulus % operators aren't registering or working even when all the other 4 binary operators are working just fine.
So I'd appreciate if you guys could just take a look and offer some assistance on how I can modify it to work. Thanks in advance!
A simple example would be: if you were to enter an operation such as
String[] go = {"1^2"} or String[] go = {"1%2"} at the start of the code and compile, it would automatically defer to Wrong expression:
1^2 or Wrong expression: 1%2 respectively.
Here's the code as is on Study.com:
public static void main(String[] args) {
String[] go = {"1+2"};
if (go.length != 1) {
System.out.println("Usage: java EvaluateExpression \"expression\"");
System.exit(1);
}
try {
System.out.println(evaluateExpression(go[0]));
}
catch (Exception ex) {
System.out.println("Wrong expression: " + go[0]);
}
}
public static int evaluateExpression(String expression) {
Stack<Integer> operandStack = new Stack<>();
Stack<Character> operatorStack = new Stack<>();
expression = insertBlanks(expression);
String[] tokens = expression.split(" ");
for (String token: tokens) {
if (token.length() == 0)
continue;
else if (token.charAt(0) == '+' || token.charAt(0) == '-') {
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '+' ||
operatorStack.peek() == '-' ||
operatorStack.peek() == '*' ||
operatorStack.peek() == '^' ||
operatorStack.peek() == '%' ||
operatorStack.peek() == '/')) {
processAnOperator(operandStack, operatorStack);
}
operatorStack.push(token.charAt(0));
}
else if (token.charAt(0) == '*' || token.charAt(0) == '/') {
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '*' ||
operatorStack.peek() == '/')) {
processAnOperator(operandStack, operatorStack);
}
operatorStack.push(token.charAt(0));
}
else if (token.trim().charAt(0) == '(') {
operatorStack.push('(');
}
else if (token.trim().charAt(0) == ')') {
while (operatorStack.peek() != '(') {
processAnOperator(operandStack, operatorStack);
}
operatorStack.pop();
}
else {
operandStack.push(new Integer(token));
}
}
while (!operatorStack.isEmpty()) {
processAnOperator(operandStack, operatorStack);
}
return operandStack.pop();
}
public static void processAnOperator(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop();
int op1 = operandStack.pop();
int op2 = operandStack.pop();
if (op == '+') operandStack.push(op2 + op1);
else if (op == '-') operandStack.push(op2 - op1);
else if (op == '*') operandStack.push(op2 * op1);
else if (op == '/') operandStack.push(op2 / op1);
else if (op == '^') operandStack.push(op2 ^ op1);
else if (op == '%') operandStack.push(op2 % op1);
}
public static String insertBlanks(String s) {
String result = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(' || s.charAt(i) == ')' ||
s.charAt(i) == '+' || s.charAt(i) == '-' || s.charAt(i) == '^' || s.charAt(i) == '%' ||
s.charAt(i) == '*' || s.charAt(i) == '/')
result += " " + s.charAt(i) + " ";
else
result += s.charAt(i);
}
return result;
}
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+
Write a class with a constructor that accepts a String object as its argument. The class should have a method that
returns the number of vowels in the string, and another method that returns the number of consonants in the string.
Demonstrate the class in a program that performs the following steps:
The user is asked to enter a string.
The program displays the following menu:
a: Count the number of vowels in the string
b: Count the number of consonants in the string
c: Count both the vowels and consonants in the string
d: Enter another string
e: Exit the program.
The program performs the operation selected by the user and repeats until the user selects e, to exit the program.
When the user enters a string and checks for consonants, or vowels, or both once, it works just fine.
But when it is passed again, the program doubles the value.
Thoughts?
Class:
public class CounterClass
{
String string;
int vow = 0;
int con = 0;
char letter = ' ';
int enter = 0;
/**
* This is a Constructor
* It accepts a string object.
*/
public CounterClass(String aString)
{
this.string = aString;
}
/* #returns an int
* This method checks for char and then adds it to a vowel counter */
public int getVowels(String aString)
{
int length = aString.length();
for( int i = 0; i < length ; i++)
{
char c = aString.charAt(i);
if (c == 'a' || c == 'e' || c == 'i'|| c == 'o'
|| c == 'u' ||c == 'A' || c == 'E' || c == 'I'
|| c == 'O' || c == 'U')
{
vow++;
}
}
return vow;
}
/* #returns an int
* This method checks for char and then adds it to a con counter */
public int getConsonants(String aString)
{
int length = aString.length();
for( int i = 0; i < length ; i++)
{
char c = aString.charAt(i);
if (c == 'B' || c == 'C' || c == 'D'|| c == 'F'
|| c == 'G' ||c == 'H' || c == 'J' || c == 'K'
|| c == 'L' || c == 'M'|| c == 'N' || c == 'P'|| c == 'Q'
|| c == 'R' ||c == 'S' || c == 'T' || c == 'V'
|| c == 'W' || c == 'X'|| c == 'Z' || c == 'b' || c == 'c' || c == 'd'|| c == 'f'
|| c == 'g' ||c == 'h' || c == 'j' || c == 'k'
|| c == 'l' || c == 'm'|| c == 'n' || c == 'p'|| c == 'q'
|| c == 'r' ||c == 's' || c == 't' || c == 'v'
|| c == 'w' || c == 'x'|| c == 'z')
{
con++;
}
}
return con;
}
}
Main Program :
import javax.swing.JOptionPane;
public class NumberCounters
{
public static void main(String [] args)
{
//Declaring variable for later use.
String input = " ";
String letters = " ";
char letter = ' ';
StringBuilder sb = new StringBuilder();
//This creates an instance of CounterClass
CounterClass string = new CounterClass(input);
//Tests
System.out.println(string.getVowels(input));
System.out.println(string.getConsonants(input));
input = JOptionPane.showInputDialog("Please enter a string"); // Getting a string input from the user.
//Does a loop until the user selects 'e'
do{
//sets 'letters' to the inputdialog from the menu
letters = JOptionPane.showInputDialog(
"a: Count the number of vowels in the string\n" +
"b: Count the number of consonants in the string\n" +
"c: Count both the vowels and consonants in the string\n"+
"d: Enter another string\n" + "e: Exit the program");
letter = letters.charAt(0); // letters is a string so I used charAt to grab the first letter from the input.
switch(letter)
{
case 'A':
case 'a': JOptionPane.showMessageDialog(null, "You have " + string.getVowels(input) + " vowels in your string");
break;
case 'B':
case 'b': JOptionPane.showMessageDialog(null, "You have " + string.getConsonants(input) +
" consonants in your string");
break;
case 'C':
case 'c': JOptionPane.showInputDialog(null, "You have " + string.getConsonants(input)
+ " Consonants and " + string.getVowels(input)
+ " vowels in your string");
break;
case 'D':
case 'd': input = JOptionPane.showInputDialog("Please enter a string");
break;
case 'E':
case 'e':
System.exit(0);
}
}while( letter != 'e');
}
}
try setting your values back to 0 in each method you could also remove the getConsonants method and just place an else(example of edited code below)
public int getVowels(String aString)
{
//set values to back to 0 before checking
vow = 0;
con = 0;
int length = aString.length();
for( int i = 0; i < length ; i++)
{
char c = aString.charAt(i);
if (c == 'a' || c == 'e' || c == 'i'|| c == 'o'
|| c == 'u' ||c == 'A' || c == 'E' || c == 'I'
|| c == 'O' || c == 'U')
{
vow++;
}
else if(c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' || c == '0' ||){
//in case you add numbers put here
}
else
{
con++;
}
}
return vow;