I am currently studying Swift.
Now that I understand the basic syntax, I want to make a calculator that can calculate correctly.
I understand that the RPN calculator is a useful introduction to programming correct formulas.
I could write a program that can calculate RPN-like from a string, but I don't really understand how to make the formula RPN-oriented.
Example) For 1+3+4×2, if you calculate from the beginning, it will be 16
The string "1 3 4 2 × + +" is calculated by RPN to 12
Reference
http://www.rpn.jp/lecture/rpn/rpn100/rpn101.html
https://knowledge.sakura.ad.jp/220/
I'd like to program the RPN string, what should I do?
You can use various buttons to enter.
*Swift doesn't know how to write stack, so it's quite a forced source.
funcalcString(_str:String){
letarr: [String] = str.components(separatedBy:"")
var stack : String = [ ]
// split
for dat in ar {
// print(dat)
if isOnlyNumber(dat){
// Numeric only
stack.append(dat)
} else{
// not just numbers
if(isOnlyArthmatic(dat)){
// More than one stack?
if(stack.count>=2){
Let num1: Double=Double(stack[stack.count-1])!
Let num2: Double=Double(stack[stack.count-2])!
varres —Double = 0
// Delete two elements
stack.removeLast()
stack.removeLast()
// calculation
switch dat {
case"+":
res=num1+num2
case"-":
res=num1-num2
case "x":
res=num1*num2
case " "":
res=num1/num2
default:
break
}
stack.append(String(res))
} else {
print("error stack.count=>"+String(stack.count))
}
} else {
print("error dat=>"+dat)
}
}
}
print(stack.count)
print(stack[stack.count-1])
}
// Check if it is only.
funcisOnlyNumber(_str:String) - >Bool{
let predict=NSPredicate(format: "SELF MATCHES'\\\d+'")
return predictor.evaluate (with:str)
}
// check for signs only
funcisOnlyArthmatic(_str:String) - >Bool{
if(str=="+"||str=="-"|str=="×"||str==" ""){
return true
}
return false
}
Nice to meet you. "As for the question, ""I can handle the RPN expression expressed in a string, but how should I express the stack?"""
You can use various buttons to enter.
Therefore, if the button is pressed on the connection between the IBAction
, I will reply as if I have reached the level where I can write a program to run this function.
First of all, I think you can write the stack like this on Swift.There may be a better way to write just one example, but I think it's enough for practical use.
structure Stack <Float > {
var stack —Array<Float>=Array<Float>()
mutating func push(_item:Float)->Void{
stack.append(item)
}// end push
mutating func pop()->Float{
return stack.removeLast()
}// end pop
}// end structure Stack
(Because we use structure
instead of class
, we declare muting
before func
)
In order to display the calculation results, I think it would be good to update the label with the calculation results.
By the way, regarding the source of the question, it works as it is, but
let num1: Double=Double (stack[stack.count-1])!
Let num2: Double=Double(stack[stack.count-2])!
varres —Double = 0
// Delete two elements
stack.removeLast()
stack.removeLast()
Yes, but
let num1: Double=Double(stack.removeLast())!
Let num2: Double=Double(stack.removeLast())!
varres —Double = 0
I think it would be better to stack up.
Instead, if you want an app that has a display part and a button part, and you press the button to display the values and calculation results in the order of RPN input, you can see the appearance of an ordinary calculator.
In addition, I think that the screen will require numeric buttons (0-9 and decimal buttons), operator buttons (+, -, x, ,, other functions, etc.) and enter buttons.
Once these buttons have been placed, create three actions to connect.
First of all, I think that each of the 0
-9
and the +/-
and .
buttons are pressed to create a number according to the button you press.
That's why I created this class.
class DecimalNumber {
private var number —Float
private var friction —Float
init(){
number = 0
friction = 0
}// end init
public funcaddDigit(_digit:Int){
if reaction == 0 {
number* = 10
number + = digit
} else{
number + = digit*fraction
friction* = 0.1
}// end if digit is integer part or fractional part
}// end addDigit
public func changeSign(){
number* = -1
}// endchangeSign
public func switchToFract(){
ifaction!=0 {return}
friction = 0.1
}// end switchToFract
public func getNumber()->Float{
let currentNumber —Float=number
number = 0
return currentNumber
}// end getNumber
}// end class Digits
By creating a class like this (for example, decimal
),
0
-9
button, then decimal.addDigit
+/-
button, decimal.changeSign()
.
button is pressed, decimal.switchToFract()
While running , IBAction
corresponding to each button is used to +=
the characters of the button pressed in the numeric display field of the calculator.
Then, when the Enter button or the Function button is pressed, push
the number from the decimal to the stack.In this case, the instance of Stack
is named stack
and
When the Enter button is pressed, take the number from decimal
and just stack.push(decimal.getNumber())
to return to the next input queue
When the non-enter operator button is pressed,
1stack.push(decimal.getNumber())
just like Enter.
2 Take as many values from the stack as the operator of the pressed button (numN=stack.pop()
) and calculate with the operator
3 Rewrite the results of the calculation to the end of the stack in stack.push()
4 Display the last digit of the stack in the results section
When the Enter button is pressed, take the number from decimal
and just stack.push(decimal.getNumber())
to return to the next input queue
If the non-enter operator button is pressed,
1stack.push(decimal.getNumber())
just like Enter.
2 Take as many values from the stack as the operator of the pressed button (numN=stack.pop()
) and calculate with the operator
3 Rewrite the results of the calculation to the end of the stack in stack.push()
4 Display the last digit of the stack in the results section
"By doing so, I think we can create a minimum ""calculator application that inputs numbers and calculates by pressing the button."""
© 2024 OneMinuteCode. All rights reserved.