[Android]使用Stack实现简易计算器
前言
花了点时间帮朋友做了一个计算器,以后可能还用得着,留下来存个档。
声明
欢迎转载,但请保留文章原始出处:)
博客园:http://www.cnblogs.com
农民伯伯: http://over140.cnblogs.com
正文
private TextView mNumberText;
/** 格式化数据 */
private static final DecimalFormat mFormat = new DecimalFormat(
"###############.######");
/** 堆栈 */
private Stack<String> mMathStack = new Stack<String>();
/** 操作数 入栈 */
private void push(char obj) {
final int size = mMathStack.size();
// 清除
if ('c' == obj) {
mMathStack.clear();
mNumberText.setText("0");
return;
}
// 操作符号
if ('+' == obj || '-' == obj || '*' == obj || '/' == obj || '=' == obj) {
switch (size) {
case 0:
break;
case 2:
if ('=' != obj)
mMathStack.set(1, obj + "");// 同时输入两个操作符,后面的操作符替换前面的
break;
case 1:
if ('=' != obj)
mMathStack.push(obj + "");
break;
case 3:
String preResult = mFormat.format(calc());
mMathStack.push(preResult);
if ('=' != obj)
mMathStack.push(obj + "");
mNumberText.setText(preResult);
break;
}
return;
}
String str = "";
int location = 0;
switch (size) {
case 0:
mMathStack.push("");
case 1:
str = mMathStack.peek();
break;
case 2:
mMathStack.push("");
case 3:
location = 2;
str = mMathStack.peek();
break;
}
int len = str.length();
if ('d' == obj) {
// 删除
if (len > 1)
str = str.substring(0, len - 1);
else if (len == 1)
str = "0";
} else if ('f' == obj) {
if ("0".equals(str) || len == 0) {
return;
} else if (str.charAt(0) == '-') {
str = str.replace('-', ' ').trim();
} else {
str = '-' + str;
}
} else {
if ('.' == obj) {
if (str.indexOf(".") > 0)
return;
} else if ('0' == obj) {
if (str.length() == 0 || str.equals("0"))
return;
}
str += obj;
}
if ('.' != obj)
str = mFormat.format(parseDouble(str));
mMathStack.set(location, str);
mNumberText.setText(str);
}
private double calc() {
double result = 0.0D;
if (mMathStack.size() == 3) {
double right = parseDouble(mMathStack.pop());
String oper = mMathStack.pop();
double left = parseDouble(mMathStack.pop());
if ("+".equals(oper)) {
result = left + right;
} else if ("-".equals(oper)) {
result = left - right;
} else if ("*".equals(oper)) {
result = left * right;
} else if ("/".equals(oper)) {
if (right != 0.0D)
result = left / right;
}
}
return result;
}
/** 解析文本数据 */
private double parseDouble(String str) {
try {
return Double.parseDouble(str);
} catch (NumberFormatException e) {
return 0.0D;
}
}
/** 点击事件 */
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnDivi:// 除
push('/');
break;
case R.id.btnMult:// 乘
push('*');
break;
case R.id.btnMinus:// 减
push('-');
break;
case R.id.btnPlus:// 加
push('+');
break;
case R.id.btnClear:// C
push('c');
break;
case R.id.btn0:
push('0');
break;
case R.id.btn1:
push('1');
break;
case R.id.btn2:
push('2');
break;
case R.id.btn3:
push('3');
break;
case R.id.btn4:
push('4');
break;
case R.id.btn5:
push('5');
break;
case R.id.btn6:
push('6');
break;
case R.id.btn7:
push('7');
break;
case R.id.btn8:
push('8');
break;
case R.id.btn9:
push('9');
break;
case R.id.btnDot:
push('.');
break;
case R.id.btnEqual:// =
push('=');
break;
case R.id.btnPM:// 符号,正负数
push('f');
break;
case R.id.btnDel:// <- delete
push('d');
break;
}
}
/** 格式化数据 */
private static final DecimalFormat mFormat = new DecimalFormat(
"###############.######");
/** 堆栈 */
private Stack<String> mMathStack = new Stack<String>();
/** 操作数 入栈 */
private void push(char obj) {
final int size = mMathStack.size();
// 清除
if ('c' == obj) {
mMathStack.clear();
mNumberText.setText("0");
return;
}
// 操作符号
if ('+' == obj || '-' == obj || '*' == obj || '/' == obj || '=' == obj) {
switch (size) {
case 0:
break;
case 2:
if ('=' != obj)
mMathStack.set(1, obj + "");// 同时输入两个操作符,后面的操作符替换前面的
break;
case 1:
if ('=' != obj)
mMathStack.push(obj + "");
break;
case 3:
String preResult = mFormat.format(calc());
mMathStack.push(preResult);
if ('=' != obj)
mMathStack.push(obj + "");
mNumberText.setText(preResult);
break;
}
return;
}
String str = "";
int location = 0;
switch (size) {
case 0:
mMathStack.push("");
case 1:
str = mMathStack.peek();
break;
case 2:
mMathStack.push("");
case 3:
location = 2;
str = mMathStack.peek();
break;
}
int len = str.length();
if ('d' == obj) {
// 删除
if (len > 1)
str = str.substring(0, len - 1);
else if (len == 1)
str = "0";
} else if ('f' == obj) {
if ("0".equals(str) || len == 0) {
return;
} else if (str.charAt(0) == '-') {
str = str.replace('-', ' ').trim();
} else {
str = '-' + str;
}
} else {
if ('.' == obj) {
if (str.indexOf(".") > 0)
return;
} else if ('0' == obj) {
if (str.length() == 0 || str.equals("0"))
return;
}
str += obj;
}
if ('.' != obj)
str = mFormat.format(parseDouble(str));
mMathStack.set(location, str);
mNumberText.setText(str);
}
private double calc() {
double result = 0.0D;
if (mMathStack.size() == 3) {
double right = parseDouble(mMathStack.pop());
String oper = mMathStack.pop();
double left = parseDouble(mMathStack.pop());
if ("+".equals(oper)) {
result = left + right;
} else if ("-".equals(oper)) {
result = left - right;
} else if ("*".equals(oper)) {
result = left * right;
} else if ("/".equals(oper)) {
if (right != 0.0D)
result = left / right;
}
}
return result;
}
/** 解析文本数据 */
private double parseDouble(String str) {
try {
return Double.parseDouble(str);
} catch (NumberFormatException e) {
return 0.0D;
}
}
/** 点击事件 */
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnDivi:// 除
push('/');
break;
case R.id.btnMult:// 乘
push('*');
break;
case R.id.btnMinus:// 减
push('-');
break;
case R.id.btnPlus:// 加
push('+');
break;
case R.id.btnClear:// C
push('c');
break;
case R.id.btn0:
push('0');
break;
case R.id.btn1:
push('1');
break;
case R.id.btn2:
push('2');
break;
case R.id.btn3:
push('3');
break;
case R.id.btn4:
push('4');
break;
case R.id.btn5:
push('5');
break;
case R.id.btn6:
push('6');
break;
case R.id.btn7:
push('7');
break;
case R.id.btn8:
push('8');
break;
case R.id.btn9:
push('9');
break;
case R.id.btnDot:
push('.');
break;
case R.id.btnEqual:// =
push('=');
break;
case R.id.btnPM:// 符号,正负数
push('f');
break;
case R.id.btnDel:// <- delete
push('d');
break;
}
}
代码说明:
a). R.id这些全是界面上的按钮, 分别代表加减乘除、0-9等。
b). 基本原理:利用堆栈模型,一个操作数 + 一个操作符 + 一个操作数 完成一次运算,清空栈,把结果压入栈底。
c). 最大支持小数点前15位和后6位,大家可以调整一下,只是注意不要溢出了。
d). UI和代码就不提供下载了,需要的也可以简单的封装一下成一个工具类。
结束
堆栈模型也很好扩展支持其他的运算符,对于简单运算实现起来很方便,简单测试了一下没有问题,有问题欢迎指正 :)
分类:
4、Android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!
2011-07-06 Android开发者指南(16) —— Activity and Task Design