How to calculate string 2*2+6/3+6 - java

I want to make calculator. I don't know to split the string and calculate the result. Is there any algorithm or some easy way to get result? I have already searched for it. But it only tells infix expressions.

Using an External Library
I Google searched the term "android library for calculating math expressions in strings" and the first result was: http://mathparser.org/
If you go to that link and scroll down a bit, it actually shows an animation of how it works. There also seems to be plenty of tutorials.
Creating your own Algorithm
Whilst using an external library in this case certainly does seem to be the optimal option, if you were required to develop the algorithm yourself the use of BODMAS (or PEMDAS depending where you are from) will be critical. At least in your case however, brackets and orders would not be needed.
Your algorithm could initially iterate the string for all cases of division e.g. where the character '/' is found, then multiplication '*', then addition '+' and finally subtraction '-'.
For each case the operands would be the digits to the left and right of the operator. Then replace the immediate expression with the calculation in the overall expression.
So the steps of your recursive style algorithm may look like the following:
2*2+6/3+6
2*2+2+6
4+2+6
6+6
12
Some things you'll need to be able to do:
Convert a character to the expected integer ( hint: subtract '0' or 48 )
Consider if your operands will be longer than one character e.g. 10 (look into substrings)
Possibly think about performance improvement e.g. 4+2+6 could be calculated in one step rather than two

Related

Stucked with Reverse Polish Notation

I'm having a homework: When we input the math expression like -(2 + 3) * 1/5 , the output should be -1. After doing some research, I found that RPN algorithm is the way to solve this problem. So what I did is convert the expression from infix to postfix. But the problem is I can't determine the operands in some situations, like this:
Input: 11+((10-2)*6)+7
Infix-to-Postfix-----------
Output: 11102-6*+7+
There is no white space between "11" and "10", and between "10" and "2" so I can't determine every single operand correctly .
Because my output (postfix) is a string, I'm totally don't know how to solve this problem. Is there any idea for this?
You described the problem -- and obvious solution -- in your posting: the postfix output you chose destroys critical information from the original expression. The obvious solution is that you have to change your postfix routine to preserve that information.
The particular problem is that you can no longer parse a string of digits into the original integers. The obvious solution is to retain or insert a unique separator. When you emit (output) an integer, add some sort of punctuation. Since RPN uses only numbers and a handful of operators, choose something easy for you to detect and to read yourself: a space, comma, or anything else that would work for you.
For instance, if you use a simple space, then you'd have RPN format as
11 10 2 -6 *+7 +
When you read this in your RPN evaluator, use the separator as a "push integer" signal (or operator).
Note that I have used this separator as a terminal character on every integer, not merely a separator between consecutive integers. Making it a terminal simplifies both output processing and input parsing. Deciding whether or not to add that symbol depends on only one token (the integer), rather than making it conditional upon two adjacent tokens (requiring a small amount of context status).

How do I solve a simple String arithmetic expression such as 5-2*10?

I'm having a lot of trouble trying to do this for some reason. I have a class which wants me to evaluate a complex Java expression such as (3 + 5[3*2-4]), using recursion. I think I have an idea on how I want to approach it, but I can't seem to figure out how to solve something really simple first off - like
5-2*10
I have no clue how to do that. They don't allow you to import any outside scripts, nor are you allowed to convert it to a postfix expression.
I don't expect anybody to write me the code but if anybody could send me off in the right direction or give me a little psuedocode I'd really appreciate it - I've spent like two hours to no avail trying to understand how I could use string tokenizers and other stuff to solve it, but I always run into a wall that I don't know how to get around. Thanks a lot in advance!
Back at university, I had to do this as well.
The approach I took was to parse expressions using recursive descent. The article does a great job of providing an overview of how your parser should tokenize your input, that you can then go on to evaluate. The key you have to realize here, is that making your parser be top-down is going to make your life easier beacuse if you were to start at the bottom of the parse tree with individual characters and then use the rules to connect the characters together into larger tokens as we go is going to require you to maintain a stack and get overly complicated. As appose to this, since you know all you're doing are logical operations, you can firstly assume that your expression matches your production rules and then you can go on to look at the internal logical implications of this assumption.
These Brief Notes on Parsing actually explain very well the difference in implementations if you were to choose to build a top-down parser or a bottom-up parser. However, depending on how complex the expressions your parser needs to handle, you might choose to implement a bottom-up parser, because for all their complexities, bottomup parsing algorithms are more powerful than top-down.
The parser I built was in OCaml, and functional programming turned out to be quite a good solution for this use case.
Please let me know if you have any questions!
You could consecutively reduce sub-expressions (so called "redexes") until no more reductions are possible.
This replacement of inner expressions can be done with regular expressions:
"(\d+)([*/])(-?\d+)"
"(\d+)([+-])(-?\d+)"
"\[(-?\d+)\]"
...
Loops in loops. See Pattern, Matcher, find.
As this seems homework, I leave the further challenge to you.
Negative numbers may be a bit challenging, might try a unary minus operator.
You are asked to implement an expression analyzer.
Here is a summary of how it is usually done. You scan the string from left to right, using the following procedures alternately. Each method consumes some of the text and returns an integer value.
A method to evaluate an integer: It starts with a digit. Collect all the contiguous digits and convert that to a value.
A method to evaluate a factor: If it starts with a digit, evaluate an integer. If it starts with a '(', evaluate an expression. If not, it is an error.
A method to evaluate a term: Evaluate a factor. While the next character is a * or a /, skip it, evaluate an additional factor, and multiply or divide the previous value by the new value.
A method to evaluate a sum: Evaluate a term. While the next character is a + or a -, skip it, evaluate an additional term and add or subtract the new value to the previous value.
A method to evaluate an expression: It starts with a '('. Skip it and evaluate a sum. If the next character is a ')', skip it. If not, it is an error.
For simple String operations, like "5-2*10", one solution is:
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
I don't want to consider the idea of not importing.
Basically, this is the code for the "Calculate" button, assuming that the expression 5-2*10 was introduced in a TextField:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String r = jTextField1.getText();
try {
jTextField1.setText(engine.eval(r).toString());
} catch (ScriptException ex) {
Logger.getLogger(MegaCal.class.getName()).log(Level.SEVERE, null, ex);
}

Does java world has the counterpart Regexp::Optimizer in perl? [duplicate]

I wrote a Java program which can generate a sequence of symbols, like "abcdbcdefbcdbcdefg". What I need is Regex optimizer, which can result "a((bcd){2}ef){2}g".
As the input may contain unicodes, like "a\u0063\u0063\bbd", I prefer a Java version.
The reason I want to get a "shorter" expression is for saving space/memory. The sequence of symbols here could be very long.
In general, to find the "shortest" optimized regex is hard. So, here, I don't need ones that guarantee the "shortest" criteria.
I've got a nasty feeling that the problem of creating the shortest regex that matches a given input string or set of strings is going to be computationally "difficult". (There are parallels with the problem of computing Kolmogorov Complexity ...)
It is also worth noting that the optimal regex for abcdbcdefbcdbcdefg in terms of matching speed is likely to be abcdbcdefbcdbcdefg. Adding repeating groups may make the regex string shorter, but it won't make the regex faster. In fact, it is likely to be slower unless the regex engine unrolls the repeating groups.
The reason that I need this is due to the space/memory limits.
Do you have clear evidence that you need to do this?
I suspect that you won't save a worthwhile amount of space by doing this ... unless the input strings are really long. (And if they are long, then you'll get better results using a regular text compression algorithm to compress the strings.)
Regular expressions are not a substitute for compression
Don't use a regular expression to represent a string constant. Regular expressions are designed to be used to match one of many strings. That's not what you're doing.
I assume you are trying to find a small regex to encode a finite set of input strings. If so, you haven't chosen the best possible subject line.
I can't give you an existing program, but I can tell you how to approach writing one.
There is no canonical minimum regex form and determining the true minimum size regex is NP hard. Certainly your sets are finite, so this may be a simpler problem. I'll have to think about it.
But a good heuristic algorithm would be:
Construct a trivial non-deterministic finite automaton (NFA) that accepts all your strings.
Convert the NFA to a deterministic finite automaton (DFA) with the subset construction.
Minimize the DFA with the standard algorithm.
Use the construction from the proof of Kleene's theorem to get to a regex.
Note that step 3 does give you a unique minimum DFA. That would probably be the best way to encode your string sets.

expression evaluation with right-associativity in java

I am trying to solve a problem in which I have to solve a given expression consisting of one or more initialization in a same string with no operator precedence (although with bracketed sub-expressions). All the operators have right precedence so I have to evaluate it from right to left. I am confused how to proceed for the given problem. Detailed problem is given here : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=108
I'll give you some ideas to try:
First off, you need to recursively evaluate inside brackets. You want to do brackets from most nested to least nested, so use a regex that matches brackets with no ) inside of them. Substring the result of the computation into the part of the string the bracketed expression took up.
If there are no brackets, then now you need to evaluate operators. The reason why the question requires right precedence is to force you to think about how to answer it - you can't just read the string and do calculations. You have to consider the whole string THEN start doing calculations, which means storing some structure describing it. There's a number of strategies you could use to do this, for example:
-You could tokenize the string, either using a scanner or regexes - continually try to see if the next item in the string is a number or which of the operators it is, and push what kind of token it is and its value onto a list. Then, you can evaluate the list from right to left using some kind of case/switch structure to determine what to do for each operator (either that, or each operator is associated with what it does to numbers). = itself would address a map of variable name keys to values, and insert the value under that variable's key, and then return (to be placed into the list) the value it produced, so it can be used for another assignment. It also seems like - can be determined as to whether it's subtraction or a negative number by whether there's a space on its right or not.
-Instead of tokenization, you could use regexes on the string as a whole. But tokenization is more robust. I tried to build a calculator based on applying regexes to the whole string over and over but it's so difficult to get all the rules right and I don't recommend it.
I've written an expression evaluating calculator like this before, so you can ask me questions if you run into specific problems.

Elegant way to do variable substitution in a java string

Pretty simple question and my brain is frozen today so I can't think of an elegant solution where I know one exists.
I have a formula which is passed to me in the form "A+B"
I also have a mapping of the formula variables to their "readable names".
Finally, I have a formula parser which will calculate the value of the formula, but only if its passed with the readable names for the variables.
For example, as an input I get
String formula = "A+B"
String readableA = "foovar1"
String readableB = "foovar2"
and I want my output to be "foovar1+foovar2"
The problem with a simple find and replace is that it can be easily be broken because we have no guarantees on what the 'readable' names are. Lets say I take my example again with different parameters
String formula = "A+B"
String readableA = "foovarBad1"
String readableB = "foovarAngry2"
If I do a simple find and replace in a loop, I'll end up replacing the capital A's and B's in the readable names I have already replaced.
This looks like an approximate solution but I don't have brackets around my variables
How to replace a set of tokens in a Java String?
That link you provided is an excellent source since matching using patterns is the way to go. The basic idea here is first get the tokens using a matcher. After this you will have Operators and Operands
Then, do the replacement individually on each Operand.
Finally, put them back together using the Operators.
A somewhat tedious solution would be to scan for all occurences of A and B and note their indexes in the string, and then use StringBuilder.replace(int start, int end, String str) method. (in naive form this would not be very efficient though, approaching smth like square complexity, or more precisely "number of variables" * "number of possible replacements")
If you know all of your operators, you could do split on them (like on "+") and then replace individual "A" and "B" (you'd have to do trimming whitespace chars first of course) in an array or ArrayList.
A simple way to do it is
String foumula = "A+B".replaceAll("\\bA\\b", readableA)
.replaceAll("\\bB\\b", readableB);
Your approach does not work fine that way
Formulas (mathematic Expressions) should be parsed into an expression structure (eg. expression tree).
Such that you have later Operand Nodes and Operator nodes.
Later this expression will be evaluated traversing the tree and considering the mathematical priority rules.
I recommend reading more on Expression parsing.
Matching Only
If you don't have to evaluate the expression after doing the substitution, you might be able to use a regex. Something like (\b\p{Alpha}\p{Alnum}*\b)
or the java string "(\\b\\p{Alpha}\\p{Alnum}*\\b)"
Then use find() over and over to find all the variables and store their locations.
Finally, go through the locations and build up a new string from the old one with the variable bits replaced.
Not that It will not do much checking that the supplied expression is reasonable. For example, it wouldn't mind at all if you gave it )A 2 B( and would just replace the A and B (like )XXX 2 XXX(). I don't know if that matters.
This is similar to the link you supplied in your question except you need a different regular expression than they used. You can go to http://www.regexplanet.com/advanced/java/index.html to play with regular expressions and figure out one that will work. I used it with the one I suggested and it finds what it needs in A+B and A + (C* D ) just fine.
Parsing
You parse the expression using one of the available parser generators (Antlr or Sable or ...) or find an algebraic expression parser available as open source and use it. (You would have to search the web to find those, I haven't used one but suspect they exist.)
Then you use the parser to generate a parsed form of the expression, replace the variables and reconstitute the string form with the new variables.
This one might work better but the amount of effort depends on whether you can find existing code to use.
It also depends on whether you need to validate the expression is valid according to the normal rules. This method will not accept invalid expressions, most likely.

Categories