Evaluating math expressions in a string using regex to split the string - java

I need some with evaluating math expressions in a string.
As of now my code will work for only positive numbers.
I used regex to split the string into two separate arrays. I was able to split all the math signs in one array and all the numbers in the other. But I am unsure how to do it for negative numbers. (I dont understand the regex i just put stuff and it worked but not for negative numbers)
Anyways here is my code, Thanks in advance!`
boolean mybool = true;
String str = "1.0+2.0+3.0+4.0";
String[] numarray = str.split("[-+/%*]");
String[] signarray = str.split("[0123456789.]");
double result = 0.0;
double num1 = 0.0;
double num2 = 0.0;
String mystr = "";
//Adds each element in sign array to mystr
for(String e : signarray){
if(e != ""){
mystr+=e;
}
}
//Assign signarray new size of length mystr
signarray = new String[mystr.length()];
//Cycle through each element in str and add it to signarray
for(int i = 0; i < mystr.length(); i++){
signarray[i] = mystr.charAt(i)+"";
}
//Print each element in num array
System.out.print("Print each element in number array: ");
for(String e : numarray){
System.out.print(e+ " ");
}
System.out.println();
System.out.print("Print each element in sign array: ");
//print each element in sign array
for(String e : signarray){
System.out.print(e+ " ");
}
System.out.println();
//Prints each element in sign array and element value
for(int i = 0; i < signarray.length; i++){
System.out.println("SignArray[" + i + "] = " + signarray[i]);
}
for(int i = 2; i <= numarray.length; i++){
//this will get the first two indexes of number array
//and store them in num1 and num1 then i use another if
//statement to go sign array to get a sign to evaluate the
//two nums and store the value in result.
//hopefully you understand my logic
if(mybool == true){
num1 = Double.parseDouble(numarray[0]);
num2 = Double.parseDouble(numarray[1]);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
if(signarray[0].equals("+")){
result = num1 + num2;
System.out.println("Result = num1 + num2 = " + num1 + "+" + num2 + "= " + result );
} else if(signarray[0].equals("-")){
result = num1 - num2;
System.out.println("Result = num1 - num2 = " + num1 + "-" + num2 + "= " + result );
} else if(signarray[0].equals("/")){
result = num1 / num2;
System.out.println("Result = num1 / num2 = " + num1 + "/" + num2 + "= " + result );
} else if(signarray[0].equals("*")){
result = num1 * num2;
System.out.println("Result = num1 * num2 = " + num1 + "*" + num2 + "= " + result );
} else if(signarray[0].equals("%")){
result = num1 % num2;
System.out.println("Result = num1 % num2 = " + num1 + "%" + num2 + "= " + result );
}
mybool = false;
} else {
num2 = Double.parseDouble(numarray[i-1]);
System.out.println("Num2 = " + num2);
if(signarray[i-2].equals("+")){
result = result + num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("-")){
result = result - num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("/")){
result = result / num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("*")){
result = result * num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("%")){
result = result % num2;
System.out.println("Result after math is : " + result);
}
}
}`
Output:
Print each element in number array: 1.0 2.0 3.0 4.0
Print each element in sign array: + + +
SignArray[0] = +
SignArray[1] = +
SignArray[2] = +
num1 = 1.0
num2 = 2.0
Result = num1 + num2 = 1.0+2.0= 3.0
Num2 = 3.0
Result after math is : 6.0
Num2 = 4.0
Result after math is : 10.0
eventually i wanna be able to evaluate a string like this
//String str = "3.01+2.2/4.01*7.1%4.0--2.0";
but i dont know how to get negative numbers from sting and store in the num array.
Thanks for you help!

Ideally, you should use a parser instead of regex. However given your current requirements, it would be simple to use positive and negative lookbehinds.
(1). Operators are always preceded by a decimal number. So we split the arguments by matching any operator which appears after a decimal number (positive lookbehind).
String[] arguments = str.split("(?<=\\d)[-+/%*]");
(2). Arguments may start with an optional minus sign but are never preceded by another decimal number. So we split the operators by matching arguments not after a decimal number (negative lookbehind).
String[] operators = str.split("(?<!\\d)-?[0-9.]+");
Note however that there will be an empty operator at position 0 of the array. If you want to avoid this then there are many different methods you could use instead of String.split.

Related

How do I tell my program to ignore an instruction if a certain case is true?

I'm a very beginner java coder and I'm coding a simple calculator using swing, and I want to implement square roots into the operators. I want it to be so that in the case that the operator is a square root, the calculator wont ask for the second number.
package swingcalculator;
import javax.swing.JOptionPane;
public class SwingCalculator {
public static void main(String[] args) {
double num1, num2, answer;
String operator;
num1 = Integer.parseInt(JOptionPane.showInputDialog("Enter your first number:"));
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
switch(operator) {
case "+":
answer = num1 + num2;
break;
case "-":
answer = num1 - num2;
break;
case "*":
answer = num1 * num2;
break;
case "/":
answer = num1 / num2;
break;
case "sqrt":
answer = Math.sqrt(num1);
break;
case "^":
answer = Math.pow(num1, num2);
break;
default:
System.out.println("You have entered an invalid operator");
return;
}
if (Boolean.parseBoolean(operator) == Boolean.parseBoolean("sqrt")){
JOptionPane.showMessageDialog(null, "Square root of " + num1 + " = " + answer);
}
else{
JOptionPane.showMessageDialog(null, num1 + " " + operator + " " + num2 + " = " + answer);
}
}
Any help would be appreciated!
Put everything after the operator = line inside a conditional (you can also move the JOptionPane.showMessageDialog lines inside the appropriate block of the conditional statement, because you don't need to check operator again):
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
if (!operator.equals("sqrt")) {
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
switch (...) { ... }
JOptionPane.showMessageDialog(null, num1 + " " + operator + " " + num2 + " = " + answer);
} else {
JOptionPane.showMessageDialog(null, "Square root of " + num1 + " = " + answer);
}
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
if(!operator.equals("sqrt"){
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
}
Read the second number only if operator is not 'sqrt', however your program seems to have many anomalies, as suggested to you in comments by others

JOptionPane showMessageDialog usage

i'm beginner for java.
I have a project for final mark. I did something but i need your help.
My project is about mathematical operations. I should use JOptionPane.
I could first part InputDialog But I can't show them in the messagebox ( i used println only to see how to work). And of course the division part is very important. If you try to divide by zero it should be error and should write something about error. I'm waiting your help. Thanks a lot and best regards.
import javax.swing.JOptionPane;
public class JavaMath3 {
public static void main(String[] args) {
int num1, num2, add, sub, multi;
double div;
num1 = Integer.parseInt(JOptionPane.showInputDialog("Write 1st number."));
num2 = Integer.parseInt(JOptionPane.showInputDialog("Write 2nd number."));
add = num1+num2;
System.out.println("Addition " + add);
sub = num1-num2;
System.out.println("Subtraction " + sub);
multi = num1*num2;
System.out.println("Multiplication " + multi);
if(num2 != 0 ) {
div = (double) num1/num2;
System.out.println("Division: " + div);
}
else {
System.out.println("A number can not divided by zero.");
}
}
}
it's a very simple you can use the JOPtionPane method showMessageDialog
JOptionPane.showMessageDialog(parent, "your message");
and here's a sample code
public static void main(String[] args)
{
int num1 = Integer.parseInt(JOptionPane.showInputDialog("Write 1st number."));
int num2 = Integer.parseInt(JOptionPane.showInputDialog("Write 2nd number."));
int sum = num1 + num2;
JOptionPane.showMessageDialog(null, "sum = " + sum);
}
After update
here's a complete example
public static void main(String[] args)
{
int num1, num2, add, sub, multi;
double div;
num1 = Integer.parseInt(JOptionPane.showInputDialog("Write 1st number."));
num2 = Integer.parseInt(JOptionPane.showInputDialog("Write 2nd number."));
add = num1 + num2;
sub = num1 - num2;
multi = num1 * num2;
String result = "sum = " + add + "\n" + "sub = " + sub + "\nmul = " + multi;
if (num2 != 0)
{
div = (double) num1 / num2;
result = result + " \n div = " + div;
} else
{
result = result + " \n div = A number can not divided by zero";
System.out.println("A number can not divided by zero.");
}
JOptionPane.showMessageDialog(null, result);
}
I don't get what mean by box but if you want them all in a same dialog box you could just write this line after your else statement:
JOptionPane.showMessageDialog(null, "Addition: " + add+ "\nSubtraction: " + sub+"\nMultiplication " + multi+ "\nDivision: " + div);

How do I display "N/A" instead of max and min values in an expression evaluation?

My code works, but what I need it to do is when nothing is enter the evaluation for the highest and the lowest should be N/A. Right now all it displays is the max and min number when something isn't entered.
Example:
Press K for keyboard or F to read expressions from a file OR escape to exit:
k
Please Enter a Post-Fix Expression (eg: 5 2 *)
Application Closed
Evaluations complete....
Highest Value: -3.4028235E38
Lowest Value: 3.4028235E38
Agregate result: 0.0
Average result: NaN
Valid expressions: 0.0
Invalid Expressions: 0.0
I need the ones in bold to say n/a but i don't know how.
private static void keyboardService(){
while (true){
System.out.println("Please Enter a Post-Fix Expression (eg: 5 2 *)");
String postfix=keyboard.nextLine();
String [] elements =postfix.split(" ");
if (postfix.equals("")){
System.out.println("Application Closed");
evaluation();
System.exit(0);
}
if (elements.length == 3){
try{
num1 = Float.valueOf(elements[0]);
num2 = Float.valueOf(elements[1]);
float total;
if(elements[2].equals("+")){
total = num1 + num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("*")){
total = num1 * num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("/")){
total = num1 / num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("-")){
total = num1 - num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else{
display("Error Invalid Expression: "+ postfix);{
invalid_count = invalid_count + 1;
}
}} catch(NumberFormatException e){
display("Error Invalid Expresion: "+postfix);
invalid_count = invalid_count + 1;
} //end of second if
} else {
display("Error Invalid Expression: "+ postfix);
invalid_count = invalid_count + 1;
}
}
}//end of keyboard service
////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void calc(float total){
highest = Math.max(highest, total );
lowest= Math.min(lowest, total);
aggregate = aggregate + total;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void evaluation(){
display("Evaluations complete....");
display("Highest Value: " + highest);
display("Lowest Value: " + lowest);
display("Agregate result: " + aggregate );
display("Average result: " + aggregate/valid_count);
display("Valid expressions: " + valid_count);
display("Invalid Expressions: " + invalid_count);
}
}
Here you go:
display("Highest Value: " + (highest == Float.MIN_VALUE ? "N/A" : String.valueOf(highest)));
display("Lowest Value: " + (lowest == Float.MAX_VALUE ? "N/A" : String.valueOf(lowest)));
and so on
In the evaluation method, before you print, check highest and lowest.
if (highest < 0)
display("Highest Value: " + "N/A");
else
display("Highest Value: " + highest);
Beside the fact that a better structure for you code would be the prefered solution you could achieve it with following changes in your code.
in your method ` keyboardService()
...
String [] elements =postfix.split(" ");
boolean validInput = true;
if (postfix.equals("")){
validInput = false;
in your method evaluation()
display("Highest Value: " + (validInput ? highest : "n/a"));
display("Lowest Value: " + (validInput ? lowest : "n/a"));
display("Agregate result: " + (validInput ? aggregate : "n/a"));
display("Average result: " + (validInput ? aggregate / valid_count : "n/a"));
display("Valid expressions: " + valid_count);
display("Invalid Expressions: " + invalid_count);

Java Program Using Split to Validate Input. Simplifying, But Keeping Things Fuctional

Any help would be appreciated.
I am not trying to list the operators, ( I know that it would work that way) i want to know if i can put them in a bundle as i attempted in my code below (it did not work, anyone knows why? how to fix it?):
}
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[2]);
double answer;
String function = "[+\\-*/]+"; //this
String[] token = input.split(function);//and this
String operator = token[1];//this is the operator
if (operator.equals(function)){
for (int i = 0; i<length; i++) {
}
System.out.println("Operation is " + token[1] + ", numbers are " + token[0] + " and " + token[2]);
}
else {
System.out.println("Your entry of "+ input + " is invalid");
}
}
first you should split .you can't access token[0] before declare tokens
String function = "[+\\-*/]+"; //this
String[] token = input.split(function );//and this
then use array[index]
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[2]);
edit....
you should use .matches instead .equals because .equals looking for entire String not regular expression
complete code
Scanner scan = new Scanner(System.in);
System.out.println("enter your operation");
String input = scan.next();
String function = "[+\\-*/]+"; //this
String[] token = input.split(function);//and this
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[1]);
double answer;
String operator = input.toCharArray()[token[0].length()]+"";
if (operator.matches(function) && (token[0]+token[1]+operator).length()==input.length()) {
System.out.println("Operation is " + operator+ ", numbers are " + token[0] + " and " + token[1]);
} else {
System.out.println("Your entry of " + input + " is invalid");
}
output>>
for input "2+3" > Operation is +, numbers are 2 and 3
for input "24+45" > Operation is +, numbers are 24 and 45
for input "2++4" > Your entry of 2++4 is invalid
the code may be like this
double answer;
String function = "[+\\-*/]+"; //this
String[] token = input.split(function);//and this
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[1]);
String operator = input.substring(token[0].length,token[0].length+1)//this is the operator
if (token.length > 1){
System.out.println("Operation is " + token[1] + ", numbers are " + token[0] + " and " + token[2]);
}
else {
System.out.println("Your entry of "+ input + " is invalid");
}
}
Access token after splitting input
double num1 = Double.parseDouble(token[0]);
double num2 = Double.parseDouble(token[2]);
And
String operator = token[1];//this is the operator
wont work because delimiter wont be there in the String array after splitting.

Simple Calculator Operation

I am attempting to simplify my long code of a calculator program, but I have a road block. I have a new else if statement for each calculator operator, but what I want to do is allow the user to manually type in, on one line, the entire operation they would like to perform and have the code compute it.
Here's what I have:
do {
System.out.println("What function would you like to perform?");
System.out.print("Exit Calculator (Q), Add (+), Subtract (-), Multiply (x), Divide (/): ");
maininput = in.next();
if (maininput.equals("+")) {
System.out.print("Enter the first number to add: ");
num1 = in.nextDouble();
System.out.print("Enter the second number to add: ");
num2 = in.nextDouble();
System.out.println();
answer = num1 + num2;
System.out.println(num1 + " + " + num2 + " = " + answer);
System.out.println();
}
else if (maininput.equals("-")) {
System.out.print("Enter the first number to subtract: ");
num1 = in.nextDouble();
System.out.print("Enter the second number to subtract: ");
num2 = in.nextDouble();
System.out.println();
answer = num1 - num2;
System.out.println(num1 + " - " + num2 + " = " + answer);
System.out.println();
}
else if(maininput.equals("x")) {
System.out.print("Enter the first number to multiply: ");
num1 = in.nextDouble();
System.out.print("Enter the second number to multiply: ");
num2 = in.nextDouble();
System.out.println();
answer = num1 * num2;
System.out.println(num1 + " x " + num2 + " = " + answer);
System.out.println();
}
else if(maininput.equals("/")) {
System.out.print("Enter the first number to divide: ");
num1 = in.nextDouble();
do {
System.out.print("Enter the second number to divide: ");
num2 = in.nextDouble();
System.out.println();
if (num2 == 0) {
System.out.println("Cannot divide by 0! Please enter a different number.");
}
} while (num2 == 0);
answer = num1 / num2;
System.out.println(num1 + " / " + num2 + " = " + answer);
System.out.println();
}
else if(maininput.equals("Q") || maininput.equals("q") || maininput.equals("EXIT") || maininput.equals("exit")) {
in.close();
System.exit(0);
}
else {
System.out.println(maininput + " is not a valid operand. Please try again.");
System.out.println();
}
} while (maininput != "Q" && maininput != "q");
This is what I want the output to be:
Enter operation:
4 * 6
4 * 6 = 24
Should be able to enter any operation here on one line. I am not asking you to write my calculator for me, I am asking how to allow the computer to read in the entire operation off one line and compute it, then print it.
If you use scanner readLine then you can read a whole line
e.g.
4 * 6
This line can then be split to get three tokens
String tokens [] = line.split (" ");
then you can see what operation to do based upon token[1]
if (token[1].equals ("-") {
//lets minus token[2] from token[0]
// need to convert String to Number
}
You can use String.split and store it in an array. Then it will return an array of string, parse those back to integers. the do the operation you want. The x variable will be the result.
if(maininput.contains("+")) {
String[] stringarr = string.split("\\+");
int x = Integer.parseInt(stringarr[0]) + Integer.parseInt(stringarr[1]);
System.out.println(stringarr[0] + " + " + stringarr[1] + " = " + x);
} else if(maininput.contains("-")) {
String[] stringarr = string.split("\\-");
int x = Integer.parseInt(stringarr[0]) - Integer.parseInt(stringarr[1]);
System.out.println(stringarr[0] + " - " + stringarr[1] + " = " x);
}
... And so on.
You could try parsing the line using a Pattern object, something like this:
Pattern opPattern = Pattern.compile("(\\d+) *([+-*/]) *(\\d+)");
Matcher matcher = opPattern.matcher(userLine);
if(matcher.find()) {
int op1 = Integer.toValue(matcher.group(1));
int op2 = Integer.toValue(matcher.group(3));
String op = matcher.group(2);
if(op.equals("+")) {
// do + op ...
} else ... {
// etc...
}
} else {
// error in line, not the form of an operation
}
Have a look at the javadoc, as I'm not sure if I used the correct method names and the like, just tried to illustrate the idea...

Categories