public class rpn {
private Object[] array;
public rpn(int n){
array = new Object[n];
for(int i=0;i<n;i++){
array[i]=0;
}
}
int calculator(Object[] n){
int p=0;
if(n.length == 1 ){
return (int)n[0];
}
for(int i=0;i<n.length-2;i++){
if (n[i] instanceof Integer && n[i + 1] instanceof Integer && n[i + 2] instanceof Character && ((char) n[i + 2] == '+' ||(char) n[i + 2] == '-'||(char) n[i + 2] == '*'||(char) n[i + 2] == '/')) {
////////////////symbol check///////////////
if(n[i+2] instanceof Character && ((char)n[i+2] == '+')){
p=(int)n[i]+(int)n[i+1];
}
if(n[i+2] instanceof Character && ((char)n[i+2] == '-')){
p=(int)n[i]-(int)n[i+1];
}
if(n[i+2] instanceof Character && ((char)n[i+2] == '*')){
p=(int)n[i]*(int)n[i+1];
}
if( n[i+2] instanceof Character && ((char)n[i+2] == '/')){
if(n[i+1] instanceof Integer && ((int)n[i+1] == 0)){
break;
}
p=(int)n[i]/(int)n[i+1];
}
//////////////////////////////////////////
Object[] temparray = new Object[n.length-2];
for(int j=0;j<i;j++){
temparray[j]=n[j];
}
temparray[i]=p;
for(int j=i+3;j<n.length;j++){
temparray[j-2]=n[j];
}
return calculator(temparray);
}
if(n[i] instanceof Character && n[i+1] instanceof Character && ((char)n[i]=='+'||(char)n[i+1]=='+')){
System.out.println("your input is wrong");
break;
}
} return 0;
}
#RPN calculator
1 messages · Page 1 of 1 (latest)
public static void main(String[] args) throws Exception {
Object[] test = new Object[5];
test[0] = 1;
test[1] = 1;
test[2] = 7;
test[3] = '/';
test[4] = '+';
System.out.println(test.length);
System.out.println(test[4] instanceof Integer);
rpn peos = new rpn(5);
int result = peos.calculator(test);
System.out.println("Result: " + result);
}
}
so this is like the first version of the rpn
the question is if right now the calculator is good and how a programm should be (i have some conscernse about the class that has a private array and that i don't use it in my calculator function)
second question any features that you guys recomend
Do you implement the shunting yard ?
In computer science, the shunting yard algorithm is a method for parsing arithmetical or logical expressions, or a combination of both, specified in infix notation. It can produce either a postfix notation string, also known as Reverse Polish notation (RPN), or an abstract syntax tree (AST). The algorithm was invented by Edsger Dijkstra and name...
I did an RPN algorithm once, for Grace actually 😂 - Implementing the shunting yard algo shortened the amount of code used and upped the speed
I haven't read how you did yours, but you should take a look
It's really not necessary for a RPN calculator
I have a few comments for you but don't currently have time to write them. I'll send them once I have a few minutes.
Whats an RPN Calc do?
Oh
Oh silly me
It's just adding numbers into a stack, popping the 2 last elements, doing an operation on both of those and adding back the result to the stack.
However, the shunting yard algorithm is indeed related to that. It allows you to parse infix notation to postfix notation, reverse polish notation (RPN) or an abstract syntax tree (AST)
man i want to make that the user just type the entire expression like 5+5
man i dont have the smallest idea on how to do this
i didn't. I really can't understand it well
It's much harder. You need to parse the expression with a parsing algorithm like the shunting yard.
But to be a bit blunt, you are not there yet.
As I said, I have some constructive comments for your code but I need to have time to sit down and write them.
if(n.length == 1 ){
return (int)n[0];
}
This can crash with ClassCastException, pass '+' first
what about float / double / long ?
casting is not really proper
like you should cast to Number then nb.intValue()
which is really (int)(((Integer)n[i]).intValue())
you could get an NPE or CCE easily
like you don't even have try/catch 😂
man i really cant understand most of what you are telling me 
also your member array and constructor are useless
and my code had error and couldn't run and after impementing this it was running just fine i really didn't fully understand it tho
test[0] = null;
test[1] = null;
test[2] = "+";
//OR
test[0] = 3L;
test[1] = 1.4d;
test[2] = '+';
this.array not used anywhere
you should try an older JDK6 compiler, it would tell you what's wrong.
Problem with JDK8+ is implicit autoboxing and deboxing
so unless you use Java Free SpotBugs plugin, you won't know that there is an issue
yea but i tried using the array that my constructor initialize in the calculator function but i was experiencing many errors so i tried just not to use it
then put your function static, and no need for constructor 😄
first time trying to make anything still clueless for a lot of things
then this becomes a procedural utility class
however in both of these i don't get any error or bug
the programm returns 0 as it should do
Try:
test = new Object[] { null };
or
test = new Object[1];
ok so the problem is that the test[1] = null and i am trying to typecast to int but it is null and it can't do that
so just this can solve it right
if(n.length == 1 ){
if(n[0]==null){
return 0;
}
return (int)n[0];
}
do i try to typecast or i just want to convert the n[0] into an int?
just use instanceof Number
(null instanceof Number) == false
then you can cast to int, if it's Number
{ Double, Integer, Long, Float, BigDecimal, BigInteger, etc. }
if it's a instanceof CharSequence then s.toString().trim().charAt(0)
(i want for start just to use int numbers)
if(n.length == 1 && n[0] instanceof Integer ){
return (int)n[0];
}
with this in main Object[] test = new Object[5];
test = new Object[1];
the program do return 0 as it should
thanks very much for your comments fd26. Man i had to open like 5 tabs on google to just "translate" some words you told that i couldn't understand 
vs code
uni made us to download eclipse for java however i already had vs in my pc and it was like preety simple just to plug in java to vscode
also git init locally and git commit anything that compiles and run 😄
Eclipse let you debug and do major refactoring safely
i made like 5-8 commits in this simple 60 lines of code
didn't had any problems debugging it
nope just git and in vscode i have gitlens
first time using git had a lot of problems understanding for some reason
also you have some AIOBE exception 😂
doing n[i+2] without doing any array bound checks*
you are doing instanceof but not checking length
first of all thanks for all of this
second of all you shouldn't spend your time trying to correct my code i feel bad
You are very much welcome 🙂
you said you didn't need Eclipse / TortoiseGit 😛
I was trying to show you that it helps a lot 😄
like trying to make a good point 😛
you see how the code on the right is much easier to read ?
at least to me
i start doing the project so i could get better so just like listing what to do in my code i think it would be better for you cause i really don't want to get a completed program and call it mine HOWEVER i can really learn from what you sent and even implement some things in my code but after i understand
it is easier
like tools exist that once you got a working proof-of-concept right that mostly work
you use git and Eclispe refactoring to make it clean 😄
and ensure that you are 100% covered
I was going to show you how to use Eclipse and TortoiseGit, but i dunno
maybe I should create my own YouTube tutorial 😂 instead
i have actaully worked with eclipse in uni so i have some knowledge
isn't eclipse for java only?
in the beginning yes, nowadays no
it works also with C/C++/PHP also
and html/css/js and jsp
but the refactoring, I only do with Java
I use EditPlus instead of vscode for anything more write only 😂
vscode is now broken on Linux due to webview2
okey why you recomend eclipse more than vs? is there any reason
i think i found out why
the refactoring and debugging
for C/C++, use Visual Studio
Download the current WinMerge version 2.16.38, which was released at 2024-01-27. For detailed info on what is new, read the change log and the release notes.
so with winmerge you can just compare your 2 commits and see what you have changed ?
you can use WinMerge or TortoiseDiff
I use both, sometime it's easier with WinMerge than TortoiseGit, depends on the changes
so it also checks for bugs
YES !!!!
it's like jshint for JavaScript
or PCLint nt-lint.exe for C/C++
spotbugs works with mvn command line or Eclipse
does not work in IntelliJ or whatever
findbugs is the older version for JDK8-
and then it will "rewrite your code"
to make the code more concise
anyway try it and let me know 😄
pov me struggling to understand how the turtle works
idk i have to download 3 seperate things to do what i can do with just vscode in which i can have most of the features all of 3 apps give but in 1 place and more begginer friendly environnment
just to use the winmerge i have to go to my files and search for my commited files and then i can compare them
i still haven't figure out how to use the turtle1
i changed some things of the program cause as you guys said i didn't like that the constructor not array is being used in the program
public class rpn {
private Object[] array;
public rpn(int n){
array = new Object[n];
for(int i=0;i<n;i++){
array[i]=0;
}
}
public void setter(Object[] n){
this.array = n;
}
int calculator(){
int p=0;
if(array.length == 1 && array[0] instanceof Integer ){
return (int)array[0];
}
for(int i=0;i<array.length-2;i++){
if (array[i] instanceof Integer && array[i + 1] instanceof Integer && array[i + 2] instanceof Character && ((char) array[i + 2] == '+' ||(char) array[i + 2] == '-'||(char) array[i + 2] == '*'||(char) array[i + 2] == '/')) {
////////////////////symbol check////////////////////////////////
if(array[i+2] instanceof Character && ((char)array[i+2] == '+')){
p=(int)array[i]+(int)array[i+1];
}
if(array[i+2] instanceof Character && ((char)array[i+2] == '-')){
p=(int)array[i]-(int)array[i+1];
}
if(array[i+2] instanceof Character && ((char)array[i+2] == '*')){
p=(int)array[i]*(int)array[i+1];
}
if( array[i+2] instanceof Character && ((char)array[i+2] == '/')){
if(array[i+1] instanceof Integer && ((int)array[i+1] == 0)){
break;
}
p=(int)array[i]/(int)array[i+1];
}
///////////////////////////////////////////////////////////////
rpn temprpn = new rpn(array.length-3);
Object[] temparray = new Object[array.length-2];
for(int j=0;j<i;j++){
temparray[j]=array[j];
}
temparray[i]=p;
for(int j=i+3;j<array.length;j++){
temparray[j-2]=array[j];
}
temprpn.setter(temparray);
return temprpn.calculator();
}
if(array[i] instanceof Character && array[i+1] instanceof Character && ((char)array[i]=='+'||(char)array[i+1]=='+')){
System.out.println("your input is wrong");
break;
}
}
return 0;
}
public static void main(String[] args) throws Exception {
Object[] test = new Object[7];
test[0] = 1;
test[1] = 1;
test[2] = '+';
test[3] = 12;
test[4] = 4;
test[5] = '+';
test[6] = '+';
System.out.println(test.length);
rpn peos = new rpn(5);
peos.setter(test);
int result = peos.calculator();
System.out.println("Result: " + result);
}
}```
i changed a lot in the calculator function how it is been used
made a setter so i can change the array's values
so in the calculator method i won't call it using a parameter but i will call it from the class itself
- question is this better than it was?
2.i have in mind first to make some more changes in the calculator method so it can fix some bugs?(i don't know if there are any)
- to make the input of the user to be more like the whole expresion 5+5 and the program store it in the array
4.and final to make a gui are those good checkpoints? should i add some or remove some?
Instead of addressing your points directly, I have a few general suggestions about to make your code easier to maintain and expand.
I lied, there is one of your point I will talk about. As I mentioned before, parting infix (ex. 5 + 5) expression is much harder than you might think and in my opinion no a priority to learn. Instead, I would recommend that you concentrate on building a proper stack calculator (with a GUI or not) before investing some time in learning how to parse expressions and you can easily add it once you built something strong.
What I want to talk about first is separation of concerns. Separation of concerns is dividing your software in different components that are responsible for a specific concern (task). Properly separating your program like that makes your program more maintainable, scalable and flexible. This means that, when properly done, you can easily extend your program without too much effort or changes. It also makes parts of your code much easier to reuse in different context (ex. using same code for CLI and GUI). This saves you a lot of code and prevents a lot of mistakes.
In your program there is 2 main concerns. The calculator and the inputs. The calculator can (and should) be completely separated from your input logic. You want to have a class that don't care about how it gets the data from the user or where the data comes from. It manages the stack and the calculation. That's it. Similarly, the code that handle the user input don't really want to know about the how the calculator work. It wants to concentrate on one thing and that's getting the user input. This would mean you'd have a very simple stack calculator class that would have a few methods, such as push that adds a value in the stack, add that add the 2 last numbers in the stack and puts it back and all the other arithmetic operations you want. The input logic would be located elsewhere and would use this other class instead of being intertwined.
.
If the picture isn't clear yet, this not only brings a better organization but also allows you to simplify all the parts of your code - no need to do that much complex input parsing) it makes your code easily extendable - you can use the same calculator code for a cli, gui, web app, api, etc.
If you need too, I can always show you some code examples.
On another note, it's important to follow a proper style convention when you write your code. Here's Java's style convention. I'd suggest to checkout the naming convention first. Another note on this, take a bit more time to name your variables. A lot of your variables are one letter or generic names. It makes it difficult to understand why they are used for. Ex. a variable called p doesn't tell much about what it is, but if it was called price you know instantly what it is and what it's used for. Having a good code hygiene is essential. It makes everything so much easier. Related to that, setters shouldn't be called setter. They should say what they set. Ex. setPrice.
thanks very much for the reply it means alot. So for the next step (you insist) to make my code more easy to read with better names for variables etc. maybe some comments and better spacing. Next, when i want to make the input method i should do it in a separate file? folder? class? (i would like a more step by step or what to search on yt/google to find how to do it) so each method would be in it's own so i can update or maintain the code more easy.I would also ask is the program that i know have good? Should i try make any repairs? thanks again
I don't really want to give you a step by step. Making you think about how to separate things is part of the process. If I'm giving a step by step it robs you from the learning process. Separate the calculator and the inputs. I gave lots of information that can help you determine how to do it. For now, you don't need to separate this in multiple files, but you definitely want to create a calculator class that is standalone. That said, the way java works, you could have the main there for the cli and testing. That's really your call. Obviously, eventually, file organization and classes becomes more important. Specially when you'll add a GUI.
yt/google to find how to do it
You can google "coupling and cohesion", "single responsibility principle" and "separation of concerns".
I would also ask is the program that i know have good?
Well, as I said, there's lot in term of design to improve. So, is it good, not really-ish. There's still lots to improve.
Should i try make any repairs?
I'm not completely sure what you mean by that but I think you mean "fix" stuff. Same thing, the design is to fix. There's lots of things that are complicated for no reason but lots of it is due to the overall design of your program.
for the fix i meant like is there anything that i can maybe improve in the code as code for example if i should add anything in the calculator method like checks for the length of input and if it is like 1 or 0 prints smthing. (maybe i will figure it out myself testing the program) and for the step by step i was talking about if i make like 2 files. first file the calculator and the second the input i have 0 clue how theese two files can be "connected" and one gives data to the other(maybe this i can also figure it out by searching my own and not get it done here)
for the fix i meant like is there anything that i can maybe improve in the code as code for example if i should add anything in the calculator method like checks for the length of input and if it is like 1 or 0 prints smthing. (maybe i will figure it out myself testing the program)
I think you went over most of those with Fd26 so, I mainly looked at the code in terms of design and good practices.
for the step by step i was talking about if i make like 2 files. first file the calculator and the second the input i have 0 clue how theese two files can be "connected" and one gives data to the other(maybe this i can also figure it out by searching my own and not get it done
I understood and as I said, I don't want to give you any step by step. I want you to think about it. But, you don't have to separate this in multiple files for now.
your constructor should be Object[] not int n
there is no reason to use OOP here
Procedural static utility function is actually better in here
If you want OOP, then your calculate could return a VO (Value Object) if you wanted, instead of just int
also you could return a BigDecimal to support all JDK Number types
Your code is too convoluted, too much repetition of the same stuff
that's why I praised you to use the Eclipse refactor feature
For TortoiseGit, you need to restart explorer.exe or reboot your computer, because it's a Windows Explorer shell extension
TortoiseGit won't work in folder which are OneDrive because OneDrive icons are stronger than GIT.
constructor is void
this.array = n;
}
calculator is int cause it actaully do the math and in the end it returns 1 int so i don't know why i shouldn't be int
your constructor as is was useless
// better
rpn peos = new rpn(test);
int result = peos.calculator();
also class should be CamelCase
Even better:
public rpn(final Object... n) { this.array = (n == null) ? new Object[] { 0 } : n; }
this way you can pass a list
public rpn(final Collection<? extends Object> n) { this.array = (n == null) ? new Object[] { 0 } : n.toArray(new Object[0]); }
Now you can write JDK8+
// Using constructor : new rpn(Object... n)
int r = new rpn(1, 1, '+', 12, 4, '+', '+').calculator();
Now you can write JDK5+
// Using constructor : new rpn(Collection n)
int r = new rpn(Arrays.asList(1, 1, '+', 12, 4, '+', '+')).calculator();
here constructor is also the setter ? I think i agree with that it is not necessary to use OOP i just use it for practise, you think it is better to go to the "old version" and just do the calculator method static?if yes is there any reason for me to keep the setter constructor and array?
setter makes no sense here
Unless you want a Builder pattern
but you have only one argument, so why would you need a builder ?
;compile java
import java.util.*;
// JDK5+
public class RPN
{
private Object[] array;
public RPN(final Object... n) { this.array = (n == null) ? new Object[] { 0 } : n; }
public RPN(final Collection<? extends Object> n) { this.array = (n == null) ? new Object[] { 0 } : n.toArray(new Object[0]); }
public List<Object> toList() { return Arrays.<Object>asList(this.array); }
public String toString() { return this.toList().toString(); }
public Object[] toArray() { return Arrays.copyOf(this.array, this.array.length); }
public int calculator() { return 0; }
// Unsafe to AIOBE exception
public Object get(final int i) { return this.array[i]; }
public void set(final int i, final Object o) { this.array[i] = o; }
public static void main(String[] a)
{
// Using constructor : new rpn(Object... n)
final RPN rpn1 = new RPN(1, 1, '+', 12, 4, '+', '+');
final int r1 = rpn1.calculator();
System.out.println(rpn1);
System.out.println(r1);
// Using constructor : new rpn(Collection n)
final RPN rpn2 = new RPN(Arrays.asList(1, 1, '+', 12, 4, '+', '+'));
final int r2 = rpn2.calculator();
System.out.println(rpn2);
System.out.println(r2);
System.out.println(rpn2.toArray()[3]);
}
}
Program Output
[1, 1, +, 12, 4, +, +]
0
[1, 1, +, 12, 4, +, +]
0
12
fd26 | 265ms | java | jdk 21.0.0 | godbolt.org
so the new program after some adjustments :i added a switch method so it can check the operation
i tried first of all to make it cleaner by naming some variables better and not just p.I also modified the way the temparray is made in the for loop by combine the before 2 for loops into 1 and also some errors messages
i think now it actually a lot more readable and also i can modify it way easier
for what you said about separating what the program does in different "classes" in the calculator isn't it a bit too much to divide it into 2 classes the first is for the program to find what operation it has to do and the second to be about the creation of the new array(i had that thought of dividing it into 2 different classes)
In your situation you don't have too. The main would be where you input logic goes. Well, it depends on how much you separate your input logic too.
What is the most important to properly separate is the business logic of your calculator.
If I go on my computer later I'll try to show you an example
continue refactoring you are far from my answer 😄
but at least you are getting there 👍
i would apricieate some comments on what do what on the code that u sent cause i have some issues understanding what ur code does
for example no clue what final is
final is like const in C++, which means that variable reference won't change
so if you are not re-assigning this variable later in the code, it's more readable to declare it final to instruct the user that the reference won't change, and create a compilation error if you try to do so.
Furthermore, if you use closure later in the code, then anything used inside the closure pointing to the outer closure MUST be final