Java different Calculator basic functions problem? - java

The code below is a chunk from actual code of Calculator.What it does is that user presses a number on the calculator then as he presses "+" the number on the text field gets stored and then he presses the next number and it gets stored when he presses "=".Then in "=" if condition the addition function is performed.Now i want both addition and subtraction running at one time that is after doing addition user wants to do subtraction then HOW will i do it????
if(a.getActionCommand().equals("+"))
{
q=tf.getText();
x=Integer.parseInt(q);
}
if(a.getActionCommand().equals("-"))
{
b=tf.getText();
t=Integer.parseInt(b);
}
if(a.getActionCommand().equals("="))
{
p=tf.getText();
y=Integer.parseInt(p);
z=x+y;
//z=t-y;
w=Integer.toString(z);
tf.setText(w);
}

Calculators generally perform an = operation whenever they process an action like + or -. Try it, open the calc app on your computer now and try 3 + 5 - 1. When you press the -, the display will show 8. You can do the same with yours and handle as many + and - operations in a row as you would like. There would be some refactoring to do to the code you've posted, and one thing you could do there would be to methodize the process that you use for the = operation. You could then call that performEquals at the beginning of each + or - block.

A stack based algorithm as jcomeau_ictx suggests is a very viable solution to your problem.
Create two stacks: one that holds operators (+, -, *, /) and one that holds operands (the set of numbers 0-9).
Support the user presses: 3 + 4 - 5
Steps:
1.) Push '3' into the operand stack
2.) Push '+' into the operator stack
3.) Push '4' into the operand stack.
Since there are at least 2 operands, calculate 3 + 4 (which is 7).
4.) Pop 3 and 4. Add these two and pop them to the operand stack
5.) Pop + from the operator stack and push -.
6.) Push 5 onto the stack. Subtract these two and place result in operand stack.
General Algorithm:
Push operand (or operator) into the stack
if (operands > 2 && operator > 0)
pop both operands and one operator;
calculate result;
place result in operand stack;
reset operator stack;

How about: accept a negative number as input, then add? Or am I missing the point?
If not, then using RPN would work, no need for "=" at all. Enter two numbers, then the "+" or "-" will take the two operands off the stack, apply the operator, and push the result back onto the stack, displaying it.
Third way: instead of your code for "-", use:
if(a.getActionCommand().equals("-"))
{
b=tf.getText();
x=-(Integer.parseInt(b));
}
Not sure if I've taken everything into account on that last suggestion, but it's a start.

I assume that you have 4 operations ( +, - , ×, ÷ ), and that you're implementing a basic desktop calculator that doesn't implement order of operations. In this case, jcomeau_ictx's x=-(Integer.parseInt(b)) won't work because it can only deal with subtraction, not multiplication and division, and these stack-based solutions are overkill.
What you is 3 variables: firstNumber, operation and secondNumber. operation starts out empty (or using some value that indicates "empty"). When the user hits =, what you need to do is take the number from the display and put it into secondNumber. Then look at all 3 variables and perform the indicated in the operation variable.
When the user hits +, - , ×, or ÷, first you perform the = operation (put the user's input into secondNumber and perform the operation indicated by the operation variable). Put the result into firstNumber (and display it on the screen if you wish). Then store the operation that the user hit (+, - , ×, or ÷) in the operation variable, so that you can perform that operation the next time the user hits +, - , ×, ÷, or =.

Related

Would using this shortcut cause problems?

CONTEXT: I am making an infix calculator in Java, and am now on the point where I'm implementing unary plus and minus. An operator is unary if it comes in where a value is expected. This would be any of the following: at the start, after an operator or after an opening parenthesis.
Relevant information: (Assume what I say in this section works as intended...because it does.)
I read in a line (which is checked to be an equation beforehand), and store it as an array of strings, delimited by spaces, called readin[].
When I encounter an "operator" (plus, minus, open paren, etc) in this equation, I push it to a stack called ops. Exceptions are for closing parenthesis, which forces a calculation to the last open parenthesis, and for these unary operators.
When I encounter a "value" (ie. a known, initialized variable, or a number), I push it to the values stack. All variables must start with a letter.
I cycle through each element in readin[], keeping track with the value i, thus i is the current element, and i-1 is the previous element in the array from what we are currently looking at.
With few exceptions, all math is done after interpreting the full equation.
The Shortcut (Code):
if(readIn[i].charAt(0) == '-'){
if(ops.empty() && values.empty()){
//is unary, set negative
}
else if( readIn[i-1].charAt(0) == ops.peek() ){
//is unary, set negative
}
//it isn't unary, continue onwards
}
What it's Doing (Plain English): It checks if we've encountered a minus sign, and if we did, it checks the following. If either of the following are true, then this minus sign is deemed "unary".
If the operator stack is empty, while the the values stack is also empty. If the previous element in the equation is on the operator stack, and thus is an operator.
Why's it doing that? Because if we didn't encounter a minus sign, then we definitely didn't encounter a unary minus sign.
If we don't have anything on the stacks, then we have either catastrophically failed somewhere, or we're at the beginning of the equation. As mentioned, an operator at the start is indicative of a unary operator. (However, I don't think the operator stack is too useful in determining this, so it may be a superfluous check.)
If the last element in the string array is an operator (including open parenthesis), then we are encountering this minus sign after an operator, which is also indicative of a unary operator.
By the way, "set negative" just flips a boolean value which modifies the next incoming value, so 5 consecutive minus signs ought to "add the negative" of the next value coming in, the same way 1 minus sign does so.
The Question: Are there any inherent problems that would arise from this code, based on the information given? Maybe ones that wouldn't result from standard equations.
Yes. There is at least 1 problem with this solution. It's when you encounter an empty ops stack, but not an empty values stack, because it ends up checking both cases, if there is a value on the stack. And thus, it tries to peek in to an empty stack of operators. This obviously throws an error.
However, if you were to add a check for if the ops stack is empty, before trying to peek in and compare it, then that should work out.
This should also still fulfil the requirements in an infix calculator, as you won't ever have an empty ops stack if you are actually encountering the minus sign right after an operator (since it can't be used if you're encountering the minus sign, and not a number).....at least, not in any case that I can think of.

Sorting string so that there aren't two same characters on adjacent places [duplicate]

It's a bonus school task for which we didn't receive any teaching yet and I'm not looking for a complete code, but some tips to get going would be pretty cool. Going to post what I've done so far in Java when I get home, but here's something I've done already.
So, we have to do a sorting algorithm, which for example sorts "AAABBB" to the ABABAB. Max input size is 10^6, and it all has to happen under 1 second. If there's more than one answer, the first one in alphabetical order is the right one. I started to test different algorithms to even sort them without that alphabetical order requirement in mind, just to see how the things work out.
First version:
Save the ascii codes to the Integer array where index is the ascii code, and the value is amount which that character occurs in the char array.
Then I picked 2 highest numbers, and started to spam them to the new character array after each other, until some number was higher, and I swapped to it. It worked well, but of course the order wasn't right.
Second version:
Followed the same idea, but stopped picking the most occurring number and just picked the indexes in the order they were in my array. Works well until the input is something like CBAYYY. Algorithm sorts it to the ABCYYY instead of AYBYCY. Of course I could try to find some free spots for those Y's, but at that point it starts to take too long.
An interesting problem, with an interesting tweak. Yes, this is a permutation or rearranging rather than a sort. No, the quoted question is not a duplicate.
Algorithm.
Count the character frequencies.
Output alternating characters from the two lowest in alphabetical order.
As each is exhausted, move to the next.
At some point the highest frequency char will be exactly half the remaining chars. At that point switch to outputting all of that char alternating in turn with the other remaining chars in alphabetical order.
Some care required to avoid off-by-one errors (odd vs even number of input characters). Otherwise, just writing the code and getting it to work right is the challenge.
Note that there is one special case, where the number of characters is odd and the frequency of one character starts at (half plus 1). In this case you need to start with step 4 in the algorithm, outputting all one character alternating with each of the others in turn.
Note also that if one character comprises more than half the input then apart for this special case, no solution is possible. This situation may be detected in advance by inspecting the frequencies, or during execution when the tail consists of all one character. Detecting this case was not part of the spec.
Since no sort is required the complexity is O(n). Each character is examined twice: once when it is counted and once when it is added to the output. Everything else is amortised.
My idea is the following. With the right implementation it can be almost linear.
First establish a function to check if the solution is even possible. It should be very fast. Something like most frequent letter > 1/2 all letters and take into cosideration if it can be first.
Then while there are still letters remaining take the alphabetically first letter that is not the same as previous, and makes further solution possible.
The correct algorithm would be the following:
Build a histogram of the characters in the input string.
Put the CharacterOccurrences in a PriorityQueue / TreeSet where they're ordered on highest occurrence, lowest alphabetical order
Have an auxiliary variable of type CharacterOccurrence
Loop while the PQ is not empty
Take the head of the PQ and keep it
Add the character of the head to the output
If the auxiliary variable is set => Re-add it to the PQ
Store the kept head in the auxiliary variable with 1 occurrence less unless the occurrence ends up being 0 (then unset it)
if the size of the output == size of the input, it was possible and you have your answer. Else it was impossible.
Complexity is O(N * log(N))
Make a bi directional table of character frequencies: character->count and count->character. Record an optional<Character> which stores the last character (or none of there is none). Store the total number of characters.
If (total number of characters-1)<2*(highest count character count), use the highest count character count character. (otherwise there would be no solution). Fail if this it the last character output.
Otherwise, use the earliest alphabetically that isn't the last character output.
Record the last character output, decrease both the total and used character count.
Loop while we still have characters.
While this question is not quite a duplicate, the part of my answer giving the algorithm for enumerating all permutations with as few adjacent equal letters as possible readily can be adapted to return only the minimum, as its proof of optimality requires that every recursive call yield at least one permutation. The extent of the changes outside of the test code are to try keys in sorted order and to break after the first hit is found. The running time of the code below is polynomial (O(n) if I bothered with better data structures), since unlike its ancestor it does not enumerate all possibilities.
david.pfx's answer hints at the logic: greedily take the least letter that doesn't eliminate all possibilities, but, as he notes, the details are subtle.
from collections import Counter
from itertools import permutations
from operator import itemgetter
from random import randrange
def get_mode(count):
return max(count.items(), key=itemgetter(1))[0]
def enum2(prefix, x, count, total, mode):
prefix.append(x)
count_x = count[x]
if count_x == 1:
del count[x]
else:
count[x] = count_x - 1
yield from enum1(prefix, count, total - 1, mode)
count[x] = count_x
del prefix[-1]
def enum1(prefix, count, total, mode):
if total == 0:
yield tuple(prefix)
return
if count[mode] * 2 - 1 >= total and [mode] != prefix[-1:]:
yield from enum2(prefix, mode, count, total, mode)
else:
defect_okay = not prefix or count[prefix[-1]] * 2 > total
mode = get_mode(count)
for x in sorted(count.keys()):
if defect_okay or [x] != prefix[-1:]:
yield from enum2(prefix, x, count, total, mode)
break
def enum(seq):
count = Counter(seq)
if count:
yield from enum1([], count, sum(count.values()), get_mode(count))
else:
yield ()
def defects(lst):
return sum(lst[i - 1] == lst[i] for i in range(1, len(lst)))
def test(lst):
perms = set(permutations(lst))
opt = min(map(defects, perms))
slow = min(perm for perm in perms if defects(perm) == opt)
fast = list(enum(lst))
assert len(fast) == 1
fast = min(fast)
print(lst, fast, slow)
assert slow == fast
for r in range(10000):
test([randrange(3) for i in range(randrange(6))])
You start by count each number of letter you have in your array:
For example you have 3 - A, 2 - B, 1 - C, 4 - Y, 1 - Z.
1) Then you put each time the lowest one (it is A), you can put.
so you start by :
A
then you can not put A any more so you put B:
AB
then:
ABABACYZ
These works if you have still at least 2 kind of characters. But here you will have still 3 Y.
2) To put the last characters, you just go from your first Y and insert one on 2 in direction of beginning.(I don't know if these is the good way to say that in english).
So ABAYBYAYCYZ.
3) Then you take the subsequence between your Y so YBYAYCY and you sort the letter between the Y :
BAC => ABC
And you arrive at
ABAYAYBYCYZ
which should be the solution of your problem.
To do all this stuff, I think a LinkedList is the best way
I hope it help :)

Is this Shunting Yard's fault or my own?

Given the expression:
1/2/3/4*5
It reaches the end of the expression and attempts to multiply out the 4 and 5 first WHICH IS WRONG because it begins to pop off the stack. I'm not necessarily doing RPN but just evaluating on the spot. How can I prevent this?
// Expression was completely read - so we should try and make sense of
// this now
while (operatorStack.size() != 0) {
ApplyOperation(operatorStack, operandStack);
}
At this point, I begin to pop off operators and operations. Since multiplication and division have the same presence, they start with multiplication.
A trace:
1/2/3/4*5
Applying * to 5 and 4
Result: 20
Applying / to 20 and 3
Result: 3/20
Applying / to 3/20 and 2
Result: 40/3
Applying / to 40/3 and 1
Result: 3/40
There is a point in the shunting yard algorithm at which you compare the precedence of the operator at the top of the stack with the precedence of the operator in the input stream, and decide whether to pop the stack (evaluate the stacked operator, in your case), or push the new operator.
It makes a big difference if the comparison is < or <=. One of those will produce left-associativity, and the other will produce right-associativity. Since you're getting right-associativity and you want left-associativity, I'm guessing (without seeing your code) that
you're using the wrong comparison operator.
By the way, your professor is quite correct. There is no need to explicitly produce RPN, and the evaluation algorithm will indeed pop the entire stack when it reaches the end of input. (The RPN algorithm would also do that; the evaluation algorithm is simply a shortcut.)
What operatorStack? The RPN resulting from the shunting-yard algorithm is a list, not a stack. It is processed from left to right, not FIFO,

addition without using + operator

Can anybody explain how this function works?
public int TestAdd(int a,int b) {
if(a <1)return b;
return(TestAdd((a&b)<<1,a^b));
}
Adding two matching set binary digits is equivalent to setting the next bit up: 1+1=2, and so on. So the function does that for all matching bits, then carries the unmatched ones over to another round. When no unmatched ones remain, it's done.
Since you can obviously test to see that it does indeed add two numbers, I assume you aren't understanding what those symbols are doing. Java's operators are described here:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
And you can easily look up the definitions of "logical AND" and "bitwise exclusive OR" and how they apply to ints.
Here we using the concept of recursion, this function call itself as values-
1 bit left shift of binary(Due to carry while adding) addition of numbers and xor of numbers until the a become <1.
Thus it returns the addition of numbers.
You can debug the function by taking some values for better understanding.

Parsing an arithmetic expression and building a tree from it in Java

I needed some help with creating custom trees given an arithmetic expression. Say, for example, you input this arithmetic expression:
(5+2)*7
The result tree should look like:
*
/ \
+ 7
/ \
5 2
I have some custom classes to represent the different types of nodes, i.e. PlusOp, LeafInt, etc. I don't need to evaluate the expression, just create the tree, so I can perform other functions on it later.
Additionally, the negative operator '-' can only have one child, and to represent '5-2', you must input it as 5 + (-2).
Some validation on the expression would be required to ensure each type of operator has the correct the no. of arguments/children, each opening bracket is accompanied by a closing bracket.
Also, I should probably mention my friend has already written code which converts the input string into a stack of tokens, if that's going to be helpful for this.
I'd appreciate any help at all. Thanks :)
(I read that you can write a grammar and use antlr/JavaCC, etc. to create the parse tree, but I'm not familiar with these tools or with writing grammars, so if that's your solution, I'd be grateful if you could provide some helpful tutorials/links for them.)
Assuming this is some kind of homework and you want to do it yourself..
I did this once, you need a stack
So what you do for the example is:
parse what to do? Stack looks like
( push it onto the stack (
5 push 5 (, 5
+ push + (, 5, +
2 push 2 (, 5, +, 2
) evaluate until ( 7
* push * 7, *
7 push 7 +7, *, 7
eof evaluate until top 49
The symbols like "5" or "+" can just be stored as strings or simple objects, or you could store the + as a +() object without setting the values and set them when you are evaluating.
I assume this also requires an order of precedence, so I'll describe how that works.
in the case of: 5 + 2 * 7
you have to push 5 push + push 2 next op is higher precedence so you push it as well, then push 7. When you encounter either a ) or the end of file or an operator with lower or equal precedence you start calculating the stack to the previous ( or the beginning of the file.
Because your stack now contains 5 + 2 * 7, when you evaluate it you pop the 2 * 7 first and push the resulting *(2,7) node onto the stack, then once more you evaluate the top three things on the stack (5 + *node) so the tree comes out correct.
If it was ordered the other way: 5 * 2 + 7, you would push until you got to a stack with "5 * 2" then you would hit the lower precedence + which means evaluate what you've got now. You'd evaluate the 5 * 2 into a *node and push it, then you'd continue by pushing the + and 3 so you had *node + 7, at which point you'd evaluate that.
This means you have a "highest current precedence" variable that is storing a 1 when you push a +/-, a 2 when you push a * or / and a 3 for "^". This way you can just test the variable to see if your next operator's precedence is < = your current precedence.
if ")" is considered priority 4 you can treat it as other operators except that it removes the matching "(", a lower priority would not.
I wanted to respond to Bill K.'s answer, but I lack the reputation to add a comment there (that's really where this answer belongs). You can think of this as a addendum to Bill K.'s answer, because his was a little incomplete. The missing consideration is operator associativity; namely, how to parse expressions like:
49 / 7 / 7
Depending on whether division is left or right associative, the answer is:
49 / (7 / 7) => 49 / 1 => 49
or
(49 / 7) / 7 => 7 / 7 => 1
Typically, division and subtraction are considered to be left associative (i.e. case two, above), while exponentiation is right associative. Thus, when you run into a series of operators with equal precedence, you want to parse them in order if they are left associative or in reverse order if right associative. This just determines whether you are pushing or popping to the stack, so it doesn't overcomplicate the given algorithm, it just adds cases for when successive operators are of equal precedence (i.e. evaluate stack if left associative, push onto stack if right associative).
The "Five minute introduction to ANTLR" includes an arithmetic grammar example. It's worth checking out, especially since antlr is open source (BSD license).
Several options for you:
Re-use an existing expression parser. That would work if you are flexible on syntax and semantics. A good one that I recommend is the unified expression language built into Java (initially for use in JSP and JSF files).
Write your own parser from scratch. There is a well-defined way to write a parser that takes into account operator precedence, etc. Describing exactly how that's done is outside the scope of this answer. If you go this route, find yourself a good book on compiler design. Language parsing theory is going to be covered in the first few chapters. Typically, expression parsing is one of the examples.
Use JavaCC or ANTLR to generate lexer and parser. I prefer JavaCC, but to each their own. Just google "javacc samples" or "antlr samples". You will find plenty.
Between 2 and 3, I highly recommend 3 even if you have to learn new technology. There is a reason that parser generators have been created.
Also note that creating a parser that can handle malformed input (not just fail with parse exception) is significantly more complicated that writing a parser that only accepts valid input. You basically have to write a grammar that spells out the various common syntax errors.
Update: Here is an example of an expression language parser that I wrote using JavaCC. The syntax is loosely based on the unified expression language. It should give you a pretty good idea of what you are up against.
Contents of org.eclipse.sapphire/plugins/org.eclipse.sapphire.modeling/src/org/eclipse/sapphire/modeling/el/parser/internal/ExpressionLanguageParser.jj
the given expression (5+2)*7 we can take as infix
Infix : (5+2)*7
Prefix : *+527
from the above we know the preorder and inorder taversal of tree ... and we can easily construct tree from this.
Thanks,

Categories