效果图
算式计算器设计思路
写一个 Formula 类,在类中写一个迭代器,在此迭代器中拆分出用户输入的算式的数字和运算符
以运算a+b-c*d/e为例:
计算时,提取出的数字放入一个集合,提取出的运算符放入一个集合。
当遇到*
/
运算符时,这两个运算符不放入运算符集合中,因为这两个符号要先计算。
当遇到*
时,此时的数字集合为a b c
,此时的运算符集合为+ -
此时,从数字集合末尾取出数字 c
,用迭代器的 next 方法从 *
的位置取出下一个数字 d
,c*d
算得的结果 r
放入数字集合
此时数字集合为 a b r
,此时运算符集合为 + -
遇到/
时也要先计算,同样从数字集合末尾取出r
,这是刚才乘得的结果,用迭代器的next
方法获得/
的下一个数字e
,r/e
算得的结果r2
放入数字集合
此时数字集合为a b r2
,此时运算符集合为+ -
最后从左到右按顺序运算
从数字集合中移除第一个数字a
,从数字集合中移除第二个数字b
,从运算符集合中移除第一个运算符 +
,计算a+b
得到结果r3
放入第一个数字结合
此时数字集合为r3 r2
,此时运算符集合为-
从数字集合中移除第一个数字r3
,从数字集合中移除第二个数字r2
,从运算符集合中移除第一个运算符 -
,计算r3-r2
的结果r4
放入第一个数字集合
此时数字集合为r4
,此时运算符集合为空
运算符为空时,停止运算
代码实现
布局文件activity_formula.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doClick"
android:text="计算" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
迭代器Formula.java
public class Formula {
private String f;
public Formula(String f) {
super();
this.f = f;
}
public class DieDaiQi {
//起始下标
int from;
//正则表达式
Matcher m = Pattern.compile("\\d+(\\.\\d)?|[+\\-*/]").matcher(f);
//判断是否有下一条的方法
public boolean hasNext() {
return from < f.length();
}
//取出下一条
public String next() {
m.find(from);
String s = m.group();
from = m.end();
return s;
}
}
//求值运算
public double eval() {
//新建集合
LinkedList<Double> list1 = new LinkedList<>();
LinkedList<String> list2 = new LinkedList<>();
//新建迭代器
DieDaiQi d = new DieDaiQi();
while (d.hasNext()) {
String s = d.next();
//数字
if (s.matches("\\d+(\\.\\d+)?")) {
list1.add(Double.parseDouble(s));
//加减
} else if (s.matches("[+\\-]")) {
list2.add(s);
//乘除
} else {
double a = list1.removeLast();
double b = Double.parseDouble(d.next());
double c = jiSuan(a, s, b);
list1.add(c);
}
}
//循环执行加减
while (list2.size() > 0) {
Double a = list1.removeFirst();
Double b = list1.removeFirst();
String s = list2.removeFirst();
double c = jiSuan(a, s, b);
list1.addFirst(c);
}
return list1.get(0);
}
private double jiSuan(double a, String s, double b) {
double r = 0;
switch (s.charAt(0)) {
case '+':
r = a + b;
break;
case '-':
r = a - b;
break;
case '*':
r = a * b;
break;
case '/':
r = a / b;
break;
}
return r;
}
}
FormulaActivity.java
public class MainActivity extends AppCompatActivity {
EditText editText;
TextView textView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_formula);
editText = findViewById(R.id.editText);
textView = findViewById(R.id.textView);
button = findViewById(R.id.button);
}
public void doClick(View v) {
switch (v.getId()) {
case R.id.button:
f1();
break;
}
}
private void f1() {
String s = editText.getText().toString();
s = s.trim();
//新建Formula对象
Formula formula = new Formula(s);
textView.setText("");
//显示拆分结果
/*Formula.DieDaiQi dieDaiQi = formula.new DieDaiQi();
while (dieDaiQi.hasNext()){
String s2 = dieDaiQi.next();
textView.append(s2+"\n");
}*/
//计算结果
Double r = formula.eval();
textView.setText(String.valueOf(r));
}
}