前言
android作业,后续有时间再补充说明
效果
代码
MainActivity.kt
package com.example.calculator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var str = "0"
private var processStr = "0"
// 能不能用小数点
private var canDot = true
// 最近用的是运算符,这一步实现运算符更改
private var useOperational = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// et_input.setOnClickListener{
//
// }
// 清空, 连计算的式子也清空
btn_clear.setOnClickListener {
str = "0"
processStr = "0"
canDot = true
useOperational = false
et_input.setText(str)
}
// 数字
btn_0.setOnClickListener {
if(str != "0"){
str += "0"
}
useOperational = false
et_input.setText(str)
}
btn_1.setOnClickListener {
if(str == "0"){
str = "1"
} else {
str += "1"
}
useOperational = false
et_input.setText(str)
}
btn_2.setOnClickListener {
if(str == "0"){
str = "2"
} else {
str += "2"
}
useOperational = false
et_input.setText(str)
}
btn_3.setOnClickListener {
if(str == "0"){
str = "3"
} else {
str += "3"
}
useOperational = false
et_input.setText(str)
}
btn_4.setOnClickListener {
if(str == "0"){
str = "4"
} else {
str += "4"
}
useOperational = false
et_input.setText(str)
}
btn_5.setOnClickListener {
if(str == "0"){
str = "5"
} else {
str += "5"
}
useOperational = false
et_input.setText(str)
}
btn_6.setOnClickListener {
if(str == "0"){
str = "6"
} else {
str += "6"
}
useOperational = false
et_input.setText(str)
}
btn_7.setOnClickListener {
if(str == "0"){
str = "7"
} else {
str += "7"
}
useOperational = false
et_input.setText(str)
}
btn_8.setOnClickListener {
if(str == "0"){
str = "8"
} else {
str += "8"
}
useOperational = false
et_input.setText(str)
}
btn_9.setOnClickListener {
if(str == "0"){
str = "9"
} else {
str += "9"
}
useOperational = false
et_input.setText(str)
}
// 小数点
btn_dot.setOnClickListener {
if (canDot && !useOperational){
str += "."
canDot = false
et_input.setText(str)
}
}
// 四则运算
btn_plus.setOnClickListener {
// 判断最近有没有用过运算符
if (str.length >= 3 && (str[str.length - 2] == '+' || str[str.length - 2] == '-' ||
str[str.length - 2] == '*' || str[str.length - 2] == '/')){
str = str.substring(0, str.length - 3)
useOperational = true
}
if (str.last() == '.')
str = str.substring(0, str.length - 1)
str += " + "
canDot = true
et_input.setText(str)
}
btn_minus.setOnClickListener {
// 判断最近有没有用过运算符
if (str.length >= 3 && (str[str.length - 2] == '+' || str[str.length - 2] == '-' ||
str[str.length - 2] == '*' || str[str.length - 2] == '/')){
str = str.substring(0, str.length - 3)
useOperational = true
}
if (str.last() == '.')
str = str.substring(0, str.length - 1)
str += " - "
canDot = true
et_input.setText(str)
}
btn_multipy.setOnClickListener {
// 判断最近有没有用过运算符
if (str.length >= 3 && (str[str.length - 2] == '+' || str[str.length - 2] == '-' ||
str[str.length - 2] == '*' || str[str.length - 2] == '/')){
str = str.substring(0, str.length - 3)
useOperational = true
}
if (str.last() == '.')
str = str.substring(0, str.length - 1)
str += " * "
canDot = true
et_input.setText(str)
}
btn_divide.setOnClickListener {
// 判断最近有没有用过运算符
if (str.length >= 3 && (str[str.length - 2] == '+' || str[str.length - 2] == '-' ||
str[str.length - 2] == '*' || str[str.length - 2] == '/')){
str = str.substring(0, str.length - 3)
useOperational = true
}
if (str.last() == '.')
str = str.substring(0, str.length - 1)
str += " / "
canDot = true
et_input.setText(str)
}
btn_del.setOnClickListener {
// 空格也要取消掉
if (str.last() == ' '){
str = str.substring(0, str.length - 1)
}
str = if (str.length >= 2)
str.substring(0, str.length - 1)
else
"0"
// 空格也要取消掉
if (str.last() == ' ' && str[str.length - 2] != '+' && str[str.length - 2] != '-'
&& str[str.length - 2] != '*' && str[str.length - 2] != '/'){
str = str.substring(0, str.length - 1)
}
if (str.length == 1) {
if (str == "-"){
str = "0"
}
canDot = true
useOperational = false
}
et_input.setText(str)
}
// 结果
btn_result.setOnClickListener {
// 判断最近有没有用过运算符
if (useOperational){
str = str.substring(0, str.length - 3)
useOperational = false
}
if (str.last() == '.')
str = str.substring(0, str.length - 1)
try{
var result = Calculator.cal("$str + 0")
processStr = str
str = result
et_input.setText(str)
canDot = true
useOperational = false
} catch (e: MyException) {
Toast.makeText(this, "运算失败,输入有误", Toast.LENGTH_SHORT).show()
}
}
// 过程
btn_process.setOnClickListener {
if (processStr != "0") {
str = processStr
processStr = "0"
et_input.setText(str)
}
}
}
}
Calculator.kt
package com.example.calculator
import java.lang.Math.pow
/*
* kotlin arrayList用法:
* https://www.yiibai.com/kotlin/kotlin-arraylist.html
* The code
* @author: andy dennis
* @time: 2020/10/17
* @detail: cal_one函数当分母为0的时候会抛出异常但不负责解决
* */
class Calculator {
companion object {
// 计算栈
fun cal(s: String): String {
var str = s
var n1: Double
var n2: Double
var tn = 0.0
var lastPriority = 0
var priority: Int
var op: Char
var numS = ArrayList<Double>()
var opS = ArrayList<Char>()
var result: Double = 0.0
var tempNumStr: String = ""
var i: Int = 0
try{
// 左闭右开
while (i < s.length) {
// 数字
if (str[i] in '0'..'9') {
tempNumStr = ""
while (i < s.length && (str[i] in '0'..'9' || str[i] == '.')) {
tempNumStr += str[i]
i++
}
tn = string2float(tempNumStr)
} else if (str[i] == ' ') {
i++
continue
} else {
numS.add(tn)
priority = getPriority(str[i])
if (priority <= lastPriority) {
// 优先级一样或者低于上一个操作符
while (opS.size != 0) {
op = opS.last()
lastPriority = getPriority(op)
if (lastPriority >= priority) {
opS.removeAt(opS.size - 1)
n2 = numS.last()
numS.removeAt(numS.size - 1)
n1 = numS.last()
numS.removeAt(numS.size - 1)
n1 = calOne(n1, op, n2)
numS.add(n1)
} else {
break
}
}
opS.add(str[i])
} else {
// 优先级高于上一个
opS.add(str[i])
}
tn = 0.0
lastPriority = priority
}
i++
}
//把最后一个操作数也加上
numS.add(tn);
while (opS.size != 0){
op = opS.last()
opS.removeAt(opS.size - 1)
n2 = numS.last()
numS.removeAt(numS.size - 1)
n1 = numS.last()
numS.removeAt(numS.size - 1)
result = calOne(n1, op, n2)
numS.add(result)
}}catch(e: MyException){
throw MyException("分母不能为零!!! from cal")
}
return beautify(result.toString())
}
private fun getPriority(op: Char): Int {
// -1 代表没有找到对应运算符
var priority: Int = -1
if (op == '+' || op == '-')
priority = 1
else if (op == '*' || op == '/')
priority = 2
else if (op == '^')
priority = 3
return priority
}
private fun calOne(n1: Double, op: Char, n2: Double): Double {
var result: Double = 0.0
if(op == '+'){
result = n1 + n2
} else if (op == '-') {
result = n1 - n2
} else if (op == '*') {
result = n1 * n2
} else if (op == '/') {
if (n2 > -0.000001 && n2 < 0.000001)
throw MyException("分母为零!!! from cal_one")
result = n1 / n2
}
return result
}
private fun beautify(s: String): String{
// 去掉小数点后多于的 0
var str = s
var flag: Boolean = true // 是否可以计算小数点后0的个数
var zeroNum: Int = 0
for (i in str.length - 1 downTo 0){
if (str[i] == '.') {
str = str.substring(0, str.length - zeroNum)
break
}
if (str[i] >= '1' && str[i] <= '9'){
flag = false
}
if (str[i] == '0' && flag) {
zeroNum++
}
}
// 去除输入为 1.0这样子的数的小数点
if (str.last() == '.')
str = str.substring(0, str.length - 1)
return str
}
private fun string2float(s: String): Double
{
var n: Double = 0.0
var isXiaoShu: Boolean = false // 判断当前的数字是不是小数部分
var xiaoShuLength: Int = 0; // 记录小数部分的长度
for (i in 0 until s.length){
if (s[i] in '0'..'9'){
n = n * 10 + (s[i] - '0').toDouble()
if (isXiaoShu)
xiaoShuLength++
}
else if (s[i] == '.'){
isXiaoShu = true //开始进入小数部分
}
}
return n * 1.0 / pow(10.0, xiaoShuLength.toDouble())
}
}
}
public class MyException(override val message: String) : Throwable(){
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:textColor="#ecf0f1"
android:background="#1abc9c"
android:text="0"
android:textSize="32dp"
android:editable="false" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#95a5a6"
android:layout_gravity="center"
android:layout_marginTop="1dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btn_clear"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:text="C"
android:background="#3498db"
android:layout_margin="2dp"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_del"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:text="DEL"
android:background="#3498db"
android:layout_margin="2dp"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_divide"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:text="÷"
android:background="#3498db"
android:layout_margin="2dp"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_multipy"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:text="×"
android:layout_margin="2dp"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_gravity="center"
android:background="#95a5a6"
android:layout_width="match_parent"
android:layout_height="98dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btn_7"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:text="7"
android:layout_gravity="right"
android:layout_margin="2dp"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_8"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="8"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_9"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="9"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_minus"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="-"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:background="#95a5a6"
android:layout_height="98dp"
android:orientation="horizontal"
android:layout_weight="1"
>
<Button
android:id="@+id/btn_4"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:text="4"
android:layout_margin="2dp"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_5"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="5"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_6"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="6"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_plus"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="+"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_gravity="left"
android:background="#95a5a6"
android:layout_width="match_parent"
android:layout_height="98dp"
android:orientation="horizontal"
android:layout_weight="1"
>
<Button
android:id="@+id/btn_1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:text="1"
android:layout_margin="2dp"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="2"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_3"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="3"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_result"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:text="="
android:layout_margin="2dp"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="98dp"
android:background="#95a5a6"
android:layout_gravity="left"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="@+id/btn_0"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="0"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_dot"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_margin="2dp"
android:text="."
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
<Button
android:id="@+id/btn_process"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="98dp"
android:layout_gravity="right"
android:layout_marginLeft="2dp"
android:text="式子"
android:background="#3498db"
android:textColor="#ecf0f1"
android:textSize="20dp" />
</LinearLayout>
</LinearLayout>