这次安卓开发课程要我们做一个简单的计算器但是要能实现基本的计算功能要有比较美观的界面,水平有限只做了一个简单的只能实现带括号的四则运算
界面布局
代码设计
主界面设计(activity_main.xml)代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/background3"/>
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="0"
android:textColorHint="#3333FF"
android:textSize="40sp"
android:textColor="#3333FF"
android:maxLines="1"
android:cursorVisible="false"
android:scrollbars="vertical"
android:background="@null"
android:gravity="center_vertical|end"
android:inputType="textMultiLine"/>
<TextView
android:id="@+id/ans"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#0000CC"
android:textSize="40sp"
android:maxLines="1"
android:layout_below="@id/edit"
android:layout_marginTop="45dp"
android:gravity="end"/>
<LinearLayout
android:id="@+id/l1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ans"
style="@style/greenStyle"
android:layout_marginTop="45dp">
<Button
android:id="@+id/btnClear"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="C"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"/>
<Button
android:id="@+id/btn01"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="("
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btnClear"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btn02"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text=")"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn01"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btndiv"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="÷"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#EE0000"
android:layout_alignLeft="@id/btn02"
android:layout_marginLeft="5dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/l2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/l1"
android:layout_marginTop="2dp"
style="@style/greenStyle">
<Button
android:id="@+id/btn7"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="7"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"/>
<Button
android:id="@+id/btn8"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="8"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn7"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btn9"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="9"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn8"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btnmulti"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="×"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#EE0000"
android:layout_alignLeft="@id/btn9"
android:layout_marginLeft="5dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/l3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/l2"
android:layout_marginTop="2dp"
style="@style/greenStyle">
<Button
android:id="@+id/btn4"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="4"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"/>
<Button
android:id="@+id/btn5"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="5"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn4"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btn6"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="6"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn5"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btnsub"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="-"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#EE0000"
android:layout_alignLeft="@id/btn6"
android:layout_marginLeft="5dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/l4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/l3"
android:layout_marginTop="2dp"
style="@style/greenStyle">
<Button
android:id="@+id/btn1"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="1"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"/>
<Button
android:id="@+id/btn2"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="2"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn1"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btn3"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="3"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn2"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btnadd"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="+"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#EE0000"
android:layout_alignLeft="@id/btn3"
android:layout_marginLeft="5dp"/>
</LinearLayout>
<LinearLayout
android:id="@+id/l5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/l4"
android:layout_marginTop="2dp"
style="@style/greenStyle">
<Button
android:id="@+id/btndel"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="del"
android:textColor="#FFFFFF"
android:textAllCaps="false"
android:textSize="40sp"
android:background="#00E5EE"/>
<Button
android:id="@+id/btn0"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="0"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btndel"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btnpoint"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="."
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#00E5EE"
android:layout_alignLeft="@id/btn0"
android:layout_marginLeft="5dp"/>
<Button
android:id="@+id/btnequal"
android:layout_width="0dp"
android:layout_height="80dp"
android:layout_weight="1"
android:text="="
android:textColor="#FFFFFF"
android:textSize="40sp"
android:background="#EE0000"
android:layout_alignLeft="@id/btnpoint"
android:layout_marginLeft="5dp"/>
</LinearLayout>
</RelativeLayout>
样式界面设计(styles.xml)代码:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="greenStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#00FF33</item>
</style>
</resources>
其中背景图片为
background3.png
至此界面基本完成
算法实现
利用之前数据结构学过的中缀表达式,但是之前是用C++实现的
核心代码(calcalator.h)如下:
#pragma once
#ifndef _Calculator_h
#define _Calculator_h
#include<iostream>
#include<assert.h>
#include<unordered_map>
#include<cstring>
#include"stack.h"
using namespace std;
unordered_map<char, int> isp, icp; //*****
Seqstack<char> m;
char c[100], d[100];
double num[100];
void charToDouble(const char* ch, long double& res) //把字符串变为浮点数
{
sscanf_s(ch, "%lf", &res);
}
class Calculator
{
private:
Seqstack<long double> s;
void Addoperator(long double value); //进操作数栈
bool Get2operator(long double &left, long double &right); //从栈中退出两个操作数
void Dooperator(char op);
public:
Calculator(int sz) :s(sz) {}
void Run();
void Clear();
};
void Calculator::Dooperator(char op)
{
long double left, right, value; bool result;
result = Get2operator(left, right);
if (result)
{
switch (op)
{
case '+': {value = left + right; /*printf("\n加入栈中的元素为%lf\n", value);*/ s.push(value); break; }
case '-': {value = left - right; /*printf("\n加入栈中的元素为%lf\n", value);*/ s.push(value); break; }
case '*': {value = left * right; /*printf("\n加入栈中的元素为%lf\n", value);*/ s.push(value); break; }
case '/':
{
if (right == 0) { cout << "Divide by 0!" << endl; Clear(); }
else { value = left / right; /*cout << "加入栈中的元素为" << value << endl;*/ s.push(value); }
break; //****
}
}
}
else Clear(); //****
}
bool Calculator::Get2operator(long double &left, long double &right)
{
if (s.Isempty()) { cout << "缺少右操作数" << endl; return false; }
s.pop(right); /*printf("\n右操作数是:%lf\n", right);*/
if (s.Isempty()) { cout << "缺少左操作数" << endl; return false; }
s.pop(left); /*printf("\n左操作数是:%lf\n", left);*/
return true;
}
void Calculator::Addoperator(long double value)
{
s.push(value);
}
void Calculator::Run()
{
isp['#'] = icp['#'] = 0; isp['('] = 1; isp['*'] = isp['/'] = isp['%'] = 5; isp['+'] = isp['-'] = 3; isp[')'] = 6;
icp['('] = 6; icp['*'] = icp['/'] = icp['%'] = 4; icp['+'] = icp['-'] = 2; icp[')'] = 1;
char ch = '#', ch1, op, tag[10000]; int l = 0, i = 0, k = 0, n = 0, w = 0; long double newoperand;
m.push(ch); cin.get(ch); tag[w++] = ch; if (ch == '-') { c[l++] = '-'; cin.get(ch); } //第一个输入是负号
while (!m.Isempty())
{
if (isdigit(ch) || ch == '.' || (ch == '-' && tag[w - 2] == '(')) { /*cout << ch;*/ c[l++] = ch; cin.get(ch); tag[w++] = ch; }
else
{
c[l++] = ' ';
m.gettop(ch1);
if (isp[ch1] < icp[ch]) { m.push(ch); cin.get(ch); tag[w++] = ch; }
else if (isp[ch1] > icp[ch]) { m.pop(op); /*cout << op;*/ c[l++] = op; }
else { m.pop(op); if (op == '(') { cin.get(ch); tag[w++] = ch; } }
}
}
//cout << c << endl;
//cout << tag << endl;
//for (i = 0; i < l; ++i) { cout << c[i]; } cout << endl;
if (c[0] == '-') { d[0] = c[0]; k++; n = 1; }
for (i = n; i < l; ++i)
{
if (isdigit(c[i]) || c[i] == '.' || (c[i] == '-' && isdigit(c[i + 1]))) { d[k++] = c[i]; }
if (c[i] == ' ' && isdigit(c[i - 1])) { d[k++] = '\0'; charToDouble(d, newoperand); Addoperator(newoperand); k = 0; }
if (c[i] == '+' || (c[i] == '-'&& !isdigit(c[i + 1])) || c[i] == '/' || c[i] == '*') { Dooperator(c[i]); }
}
long double ans;
if (s.pop(ans)) { printf("%.8lf\n", ans); }
}
void Calculator::Clear()
{
s.makeempty();
}
#endif
将改代码转为java好困难,debug了我一天,去请教大佬,借鉴了他的代码(calculator1.java)
package y;
import java.util.*;
/**
* 计算器
* @author CJH
*/
public class Calculator1 {
private static final Map<Character, Integer> basic = new HashMap<Character, Integer>();
static {
basic.put('-', 1);
basic.put('+', 1);
basic.put('*', 2);
basic.put('/', 2);
basic.put('(', 0);
//在运算中 ()的优先级最高,但是此处因程序中需要 故设置为0
}
private String toPostfix(String infix){
//定义队列 用于存储 数字 以及最后的 后缀表达式
List<String> queue = new ArrayList<>();
//定义栈 用于存储 运算符 最后stack中会被 弹空
List<Character> stack = new ArrayList<>();
//判定标准 将表达式中会出现的运算符写出来
String standard = "*/+-()";
//对于第一个为负数的进行预处理,例如-3*6 ->(0-3)/*6
if (infix.charAt(0) == '-'){
StringBuilder stringBuilder = new StringBuilder(infix);
stringBuilder.insert(0,"(0");
int i = 3;
while(i < stringBuilder.length()){
if (standard.indexOf(stringBuilder.charAt(i)) == -1){
i++;
continue;
}else{
break;
}
}
stringBuilder.insert(i,')');
infix = stringBuilder.toString();
}
//字符数组 用于拆分数字或符号
char[] charArr = infix.toCharArray();
//在循环中用来保存 字符数组的当前循环变量的 这里仅仅是初始化一个值 没有意义
char ch;
//用于记录字符长度 【例如100*2,则记录的len为3 到时候截取字符串的前三位就是数字】
int len = 0;
//开始迭代
for (int i = 0; i < charArr.length; i++) {
//保存当前迭代变量
ch = charArr[i];
//如果当前变量为 数字
if(Character.isDigit(ch)) {
len++;
//如果当前变量为 . 会出现在小数里面
}else if(ch=='.'){
len++;
//如果是上面标准中的 任意运算一个符号
}else if(standard.indexOf(ch) != -1) {
//长度也有
if(len > 0) {
//说明符号之前的可以截取下来做数字
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i)));
//长度置空
len = 0;
}
//如果是左括号
if(ch == '(') {
//将左括号 放入栈中
stack.add(ch);
//跳出本次循环 继续找下一个位置
continue;
}
//如果栈不为empty,
if (!stack.isEmpty()) {
//获取栈的大小-1 即代表栈最后一个元素的下标
int size = stack.size() - 1;
//设置标志位
boolean flag = false;
//若当前ch为右括号,则 栈里元素从栈顶一直弹出,直到弹出到 左括号
while (size >= 0 && ch == ')' && stack.get(size) != '(') {
//注意此处条件:ch并未入栈,所以并未插入队列中;同样直到找到左括号的时候,循环结束了,所以左括号也不会放入队列中【也就是:后缀表达式中不会出现括号】
queue.add(String.valueOf(stack.remove(size)));
//size-- 保证下标永远在栈最后一个元素【栈中概念:指针永远指在栈顶元素】
size--;
//设置标志位为true 表明一直在取()中的元素
flag = true;
}
//若取得不是()内的元素,并且当前栈顶元素的优先级>=对比元素 那就出栈插入队列
while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) {
//同样 此处也是remove()方法,既能得到要获取的元素,也能将栈中元素移除掉
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
//若当前元素不是右括号
if(ch != ')') {
//就要保证这个符号 入栈
stack.add(ch);
} else {
//否则就要出栈 栈内符号
stack.remove(stack.size() - 1);
}
}
if(i == charArr.length - 1) {
//如果已经走到了 中缀表达式的最后一位
if(len > 0) {
//如果len>0 就截取数字
queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1)));
}
int size = stack.size() - 1;
//size表示栈内最后一个元素下标
while (size >= 0) {
//一直将栈内 符号全部出栈 并且加入队列中 【最终的后缀表达式是存放在队列中的,而栈内最后会被弹空】
queue.add(String.valueOf(stack.remove(size)));
size--;
}
}
}
StringBuilder res = new StringBuilder();
while(!queue.isEmpty()){
res.append(queue.remove(0));
res.append(",");
}
res.deleteCharAt(res.length()-1);
return res.toString();
//将队列中元素以,分割 返回字符串
}
/**
* 计算
* @param infix 中缀表达式
* @return 计算结果
*/
public String run(String infix) throws ArithmeticException,NullPointerException{
//计算栈
Stack<Double> stack = new Stack<>();
//转换成后缀表达式
String postfix = toPostfix(infix);
String[] array = postfix.split(",");
String standard = "*/+-";
for (String str : array) {
if (standard.indexOf(str.charAt(0)) != -1) {
//进行运算
double right = stack.pop();
double left = stack.pop();
char ch = str.charAt(0);
double result=0;
switch (ch) {
case '+':
result = left + right;
break;
case '-':
result = left - right;
break;
case '*':
result = left * right;
break;
case '/':
if (right == 0) {
//抛出异常
throw new ArithmeticException("被除数不能为0");
} else {
result = left / right;
}
break;
default:
break;
}
//操作数压栈
stack.push(result);
} else {
//操作数压栈
stack.push(Double.parseDouble(str));
}
}
java.text.DecimalFormat df = new java.text.DecimalFormat("0.00000000");
return df.format(stack.pop()).toString();
}
public static void main(String []args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
Calculator1 cal = new Calculator1();
System.out.println(cal.run(s));
}
}
自己改过来后,java代码如下
package com.example.calculatorapp;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import static java.lang.Character.isDigit;
public class Calculator {
private Map<Character, Integer> isp = new HashMap<>();
private Map<Character, Integer> icp = new HashMap<>();
private Stack<Character> m = new Stack<>();
private char []c = new char[1000];
private char []d = new char[1000];
private Stack<Double> s = new Stack<>();
private double left, right;
private int flag = 0; //除以0的标记
private double charToDouble(char []ch) //把字符串变为浮点数
{
System.out.print("ch = ");
for(int i = 0; i < ch.length; ++i) {
System.out.print(ch[i]);
}
System.out.println("ch = " + String.valueOf(ch));
double res = Double.parseDouble(String.valueOf(ch));
System.out.println("res = " + res);
return res;
}
private void Addoperator(double value) { //进操作数栈
s.push(value);
}
private boolean Get2operator() { //从栈中退出两个操作数
if (s.empty()) {
Log.d("输入表达式错误", "缺少右操作数");
return false;
}
right = s.peek();
s.pop();
if (s.empty()) {
Log.d("输入表达式错误", "缺少左操作数");
return false;
}
left = s.peek();
s.pop();
return true;
}
private void Clear() //清空栈
{
while(!s.empty()){ s.pop(); }
}
private void Dooperator(char op)
{
double value;
boolean result = Get2operator();
System.out.println("left = " + left);
System.out.println("right = " + right);
if (result) {
switch (op) {
case '+': {value = left + right; System.out.println("value = " + value); s.push(value); break; }
case '-': {value = left - right; System.out.println("value = " + value); s.push(value); break; }
case '*': {value = left * right; System.out.println("value = " + value); s.push(value); break; }
case '/':
{
if (right == 0) { Log.d("除数不可以为0","除数为0");
if(left < 0) { flag = 1; }
else if(left > 0) {flag = 2;}
else if(left == 0) {flag = 3;}
Clear();
return;
}
else { value = left / right; System.out.println("value = " + value); s.push(value); }
break; //****
}
}
}
else Clear(); //****
}
public String Run(String str) {
flag = 0;
str += " "; //防止后面越界
int t = 0;
isp.put('#', 0);
icp.put('#', 0);
isp.put('(', 1);
icp.put('(', 6);
isp.put('*', 5);
icp.put('*', 4);
isp.put('/', 5);
icp.put('/', 4);
isp.put('%', 5);
icp.put('%', 4);
isp.put('+', 3);
icp.put('+', 2);
isp.put('-', 3);
icp.put('-', 2);
isp.put(')', 6);
icp.put(')', 1);
char ch = '#', ch1, op;
char[] tag = new char[10000];
int l = 0, i = 0, k = 0, n = 0, w = 0;
double newoperand = 0;
m.push(ch);
ch = str.charAt(t);
tag[w++] = ch;
if (ch == '-') {
c[l++] = '-';
t++;
ch = str.charAt(t);
} //第一个输入是负号
while (!m.empty()) {
if (isDigit(ch) || ch == '.' || (ch == '-' && tag[w - 2] == '(')) {
System.out.println("ch 1 = " + ch);
c[l++] = ch;
t++;
System.out.println("t = " + t);
ch = str.charAt(t);
System.out.println("ch = " + ch);
tag[w++] = ch;
} else {
c[l++] = ' ';
ch1 = m.peek();
int a = isp.get(ch1);
if (!icp.containsKey(ch)) {
icp.put(ch, 0); //*******
}
int b = icp.get(ch);
if (a < b) {
m.push(ch);
t++;
ch = str.charAt(t);
tag[w++] = ch;
} else if (a > b) {
op = m.peek();
m.pop();
c[l++] = op;
System.out.println("op = " + op);
} else {
op = m.peek();
m.pop();
if (op == '(') {
t++;
ch = str.charAt(t);
tag[w++] = ch;
}
}
}
}
System.out.println("c = " + c);
System.out.println("tag = " + tag);
for (i = 0; i < l; ++i) { System.out.print(c[i]); }
System.out.println();
if (c[0] == '-') {
d[0] = c[0];
System.out.print("d = ");
for(int j = 0; j < d.length; ++j) {
System.out.print(d[j]); }
System.out.println();
System.out.println("c[0] = " + c[0]);
k++;
System.out.println("k = " + k);
n = 1;
}
for (i = n; i < l; ++i) {
if (isDigit(c[i]) || c[i] == '.' || (c[i] == '-' && isDigit(c[i + 1]))) {
d[k++] = c[i];
System.out.println("k = " + k);
System.out.println("c[i] = " + c[i]);
System.out.print("d = ");
for(int j = 0; j < d.length; ++j) {
System.out.print(d[j]); }
System.out.println();}
if (c[i] == ' ' && (i >= 1 &&isDigit(c[i - 1]))) {
System.out.print("d = ");
for(int j = 0; j < d.length; ++j) { System.out.print(d[j]); }
System.out.println();
newoperand = charToDouble(d); //****
Addoperator(newoperand);
k = 0;
d = new char[1000];
System.out.println("k = " + k);
}
if (c[i] == '+' || (c[i] == '-' && !isDigit(c[i + 1])) || c[i] == '/' || c[i] == '*') {
Dooperator(c[i]);
if(flag == 1){ return "-∞"; }
if(flag == 2) {return "∞";}
if(flag == 3) {return "出错";}
}
}
double ans;
ans = s.peek();
// System.out.println("运算结果为: " + ans);
java.text.DecimalFormat df = new java.text.DecimalFormat("0.00000000");
// System.out.println(df.format(ans).toString());
return df.format(ans).toString();
}
}
安卓主活动(MainActvity.java)代码:
package com.example.calculatorapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.InputType;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn0, btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9;
private Button btn_equal, btn_div, btn_add, btn_sub, btn_multi;
private Button btn_point, btn01, btn02, btn_clear, btn_delete;
private TextView textView;
private EditText editText;
String rep = ""; //表达式
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn0 = (Button) findViewById(R.id.btn0);
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn3 = (Button) findViewById(R.id.btn3);
btn4 = (Button) findViewById(R.id.btn4);
btn5 = (Button) findViewById(R.id.btn5);
btn6 = (Button) findViewById(R.id.btn6);
btn7 = (Button) findViewById(R.id.btn7);
btn8 = (Button) findViewById(R.id.btn8);
btn9 = (Button) findViewById(R.id.btn9);
btn_point = (Button) findViewById(R.id.btnpoint);
btn_add = (Button) findViewById(R.id.btnadd);
btn_sub = (Button) findViewById(R.id.btnsub);
btn_div = (Button) findViewById(R.id.btndiv);
btn_multi = (Button) findViewById(R.id.btnmulti);
btn_equal = (Button) findViewById(R.id.btnequal);
btn01 = (Button) findViewById(R.id.btn01);
btn02 = (Button) findViewById(R.id.btn02);
btn_clear = (Button) findViewById(R.id.btnClear);
btn_delete = (Button) findViewById(R.id.btndel);
textView = (TextView) findViewById(R.id.ans);
editText = (EditText) findViewById(R.id.edit);
editText.setKeyListener(null);
btn0.setOnClickListener(this); //******
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
btn4.setOnClickListener(this);
btn5.setOnClickListener(this);
btn6.setOnClickListener(this);
btn7.setOnClickListener(this);
btn8.setOnClickListener(this);
btn9.setOnClickListener(this);
btn01.setOnClickListener(this);
btn02.setOnClickListener(this);
btn_delete.setOnClickListener(this);
btn_clear.setOnClickListener(this);
btn_equal.setOnClickListener(this);
btn_sub.setOnClickListener(this);
btn_add.setOnClickListener(this);
btn_point.setOnClickListener(this);
btn_div.setOnClickListener(this);
btn_multi.setOnClickListener(this);
}
@Override
public void onClick(View v){
switch(v.getId()) {
case R.id.btn0:
rep += "0";
editText.setText(rep);
break;
case R.id.btn1:
rep += "1";
editText.setText(rep);
break;
case R.id.btn2:
rep += "2";
editText.setText(rep);
break;
case R.id.btn3:
rep += "3";
editText.setText(rep);
break;
case R.id.btn4:
rep += "4";
editText.setText(rep);
break;
case R.id.btn5:
rep += "5";
editText.setText(rep);
break;
case R.id.btn6:
rep += "6";
editText.setText(rep);
break;
case R.id.btn7:
rep += "7";
editText.setText(rep);
break;
case R.id.btn8:
rep += "8";
editText.setText(rep);
break;
case R.id.btn9:
rep += "9";
editText.setText(rep);
break;
case R.id.btnadd:
rep += "+";
editText.setText(rep);
break;
case R.id.btnsub:
rep += "-";
editText.setText(rep);
break;
case R.id.btndiv:
rep += "÷";
editText.setText(rep);
break;
case R.id.btnmulti:
rep += "×";
editText.setText(rep);
break;
case R.id.btn01:
rep += "(";
editText.setText(rep);
break;
case R.id.btn02:
rep += ")";
editText.setText(rep);
break;
case R.id.btndel:
rep = rep.substring(0, rep.length() - 1); //*****退格,删除最后一位
editText.setText(rep);
break;
case R.id.btnClear:
rep = ""; //清空
editText.setText(rep);
break;
case R.id.btnpoint:
rep += ".";
editText.setText(rep);
break;
case R.id.btnequal:
editText.setText(rep+"="); //把式子代入
Calculator cal = new Calculator();
rep = rep.replace('÷', '/'); //记得把运算符换成计算机的符号****
rep = rep.replace('×', '*');
textView.setText(cal.Run(rep));
rep = ""; //清零,重新计算
break;
}
}
}
至此简单的计算器大功告成啦!
可是仍然存在诸多不足
不足:
(1)界面输入表达式的文本框不能实现自动换行,最多只能显示一行,显示多行的话会打乱当前的界面布局,以我目前的水平无法处理
(2)答案输出的文本框最多只能输出一行,多出的部分无法显示,若要显示会和(1)一样打乱当前的布局
(3)算法对许多特殊情况无法做出好的处理,只能对除以0的情况加以处理:
左边的数大于0,输出∞,小于0输出-∞,等于0输出“出错”
但是如果输入表达式的格式出错,app会自动结束退出,必须要求输入的格式不能错
(4)只能计算简单的带括号的四则运算,对log、exp、取模等较高级的运算无法实现
今后希望能进一步改进不足之处:
(1)完善界面,使之更加美观
(2)改进算法,用更完善的算法对各种不合理的情况加以妥善处理,并进一步实现高级的运算
(3)使文本框能输入多行并自动换行,显示最后输入的部分,输出框能尽量显示全部的结果,用多行显示,实在不行一部分再用省略号代替